OmniAuth - Facebook login not supplying email in user_info - ruby-on-rails

I'm using OmniAuth, and after logging in via Facebook, I get my omniauth.auth key, which looks like this:
user_info:
name: Tim Sullivan
urls:
Facebook: http://www.facebook.com/...
Website:
nickname: ...
last_name: Sullivan
first_name: Tim
uid: "123456789"
credentials:
token: [some token]
extra:
user_hash:
name: Tim Sullivan
timezone: -5
gender: male
id: "123456789"
last_name: Sullivan
updated_time: 2010-12-30T00:52:39+0000
verified: true
locale: en_US
link: http://www.facebook.com/...
email: tim#myemailaddress.com
first_name: Tim
provider: facebook
Now, according to the docs, the email should be in the user_info section, but it isn't. It is, however, in the extra/user_hash section. Since I'm stripping extra, it's not getting stored, so later on down the pipe I'm having problems. I could add it myself, but that doesn't explain why it's not there in the first place.
Why isn't email being put into the user_info section? A bug? Undocumented change?

moved to
email = omniauth["extra"]["raw_info"]["email"]

The hash "info" contains all the information of the User:
email = omniauth["info"]["email"]

I think the doc is not up to date. I usually get it from the extra hash before removing it.
email = omniauth["extra"]["user_hash"]["email"]

While omniauth["info"] used to and should contain the information, I have noticed that facebook seems to be giving me errors with the email which is linked to a facebook bug/(feature?). So I get intermittent errors with this hash where the email is not present which breaks everything.
After much debugging I found that the safest way to not break my code is to call the FB API with Koala or just good ol REST and get the information needed for login if omniauth["info"] does not contain the information you need.

We are using omniauth with the FB JSDK and I couldn't get the email to come back because I had overlooked the fact that FB.login() requires a 'scope' opts.
FB.login(function(response) {
// handle the response
}, {scope: 'email,user_likes'});
After adding the opts (even though the scope was set up on the server) everything was fixed.
https://developers.facebook.com/docs/reference/javascript/FB.login/v2.2#permissions

Since you're using Rails and not JavaScript (another person answered but for JS), you need to specifically ask for email to be returned from the info field hash as it isn't by default. You set this up in your config/initializers/omniauth.rb file like so:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, Rails.application.secrets.omniauth_provider_key, Rails.application.secrets.omniauth_provider_secret,
:scope => 'email', :display => 'popup', :info_fields => 'name,email'
end
This info is kind of hidden at the very end of the Configuring section on the omniauth-facebook gem's GitHub readme.

Related

Retrieving Youtube comments with fullscreen/yt

I'm using https://github.com/Fullscreen/yt to interact with Youtube API, but after a couple of hours of testing I'm unable to fetch comments from a video.
I suspect the reason is I'm requesting the wrong permissions, but I can't find anything clear in Google docs about what scope to ask. I appears from the OAuth playground it's https://www.googleapis.com/auth/youtube.force-ssl
but still, I'm not able to make it work.
This is the omniauth provider line to request a new token:
provider :google_oauth2, key, secret, {:scope => 'http://gdata.youtube.com,email,profile,youtube,youtube.force-ssl'}
And this is how I try to retrieve the comments:
Yt.configure do |config|
config.client_id = key
config.client_secret = secret
end
youtube_client = Yt::Account.new access_token: 'yadayada'
video = Yt::Video.new id: 'foobar', auth: youtube_client
puts video.comments
What I get is:
Yt::Errors::Forbidden: A request to YouTube API was considered forbidden by the server:
{"error"=>{"errors"=>[{"domain"=>"global", "reason"=>"insufficientPermissions", "message"=>"Insufficient Permission"}], "code"=>403, "message"=>"Insufficient Permission"}}
I've tried pretty much the same on channels too, same problem, that's why I guessed there's something wrong with my access_token.
Has someone done this? What am I doing wrong? Any example?
As per the documentation on the page you have shared the link of, I am not able to see this line of code:
account = Yt::Account.new authorization_code: '4/Ja60jJ7_Kw0', redirect_uri: redirect_uri
Every user who authorizes your app will be redirected to the redirect_uri with an extra code parameter that looks something like 4/Ja60jJ7_Kw0. Just pass the code to the following method to authenticate and initialize the account:
If this does not workout try Configuring with environment variables
As an alternative to the approach above, you can configure your app with variables. Setting the following environment variables:
export YT_CLIENT_ID="1234567890.apps.googleusercontent.com"
export YT_CLIENT_SECRET="1234567890"
export YT_API_KEY="123456789012345678901234567890"
is equivalent to configuring your app with the initializer:
Yt.configure do |config|
config.client_id = '1234567890.apps.googleusercontent.com'
config.client_secret = '1234567890'
config.api_key = '123456789012345678901234567890'
end
so use the approach that you prefer. If a variable is set in both places, then Yt.configure takes precedence.
Hope this Helps!!

Google OAuth 2 redirect_uri_mismatch - OmniAuth Rails app

I've a problem with authenticating Google account with my Rails app.
I'm using omniauth-google-oauth2 gem with Devise.
Always get this Error when I try to access google account:
Error: redirect_uri_mismatch
The redirect URI in the request: http://localhost:3000/users/auth/google_oauth2/callback did not match a registered redirect URI
I'm sure that the registered redirect URI in my google console app is right and identical with requested one, just like that:
so what's main the problem here?
try this way :
add require "omniauth-google-oauth2" to devise.rb in config/initializers folder
add http://localhost:3000/users/auth/google_oauth2/callback into Redirect URL in google API console https://console.developers.google.com
restart server
Mine solution is to force redirect_url in both (code/token) stages, devise.rb initializer:
CALLBACK_URL = 'https://SOMESERVER/users/auth/google_oauth2/callback'
Devise.setup do |config|
config.omniauth :google_oauth2,
"SOMECLIENTID.apps.googleusercontent.com",
"SOMEKEY",
{
:client_options => {:ssl => {:ca_file => 'C:\Ruby21\cacert.pem'}},
:provider_ignores_state => true,
:prompt => "select_account",
:redirect_uri => CALLBACK_URL,
setup: (lambda do |env|
request = Rack::Request.new(env)
env['omniauth.strategy'].options['token_params'] = {:redirect_uri => CALLBACK_URL}
end)
}
end
there is discussion about the issue here: https://github.com/zquestz/omniauth-google-oauth2/issues/181
Be careful of what client id you are setting.
Google API provides two:
Client ID for Google Compute and App Engine
Client ID for web applications
You need to use Client ID for web applications
Make sure you set up the Product Name and Email address via the Consent Screen Link.
Per the omniauth-google-oauth2 documentation you need to:
Go to 'https://console.developers.google.com'
Select your project.
Click 'APIs & auth'
Make sure "Contacts API" and "Google+ API" are on.
Go to Consent Screen, and provide a 'PRODUCT NAME'
Wait 10 minutes for changes to take effect.
I had the same issue, made the updates, waited 10 minutes, still nothing, went to lunch, then it started to work. Guess patience was part of the key to success on this one.

"The token is invalid" when trying to setup Paypal recurring payments with ActiveMerchant

I feel like a lot of the documentation on this is outdated, but this is what I have been trying so far:
I am using the ActiveMerchant::Billing::PaypalExpressGateway gateway.
First I setup the purchase and redirect the user to Paypal:
response = gateway.setup_purchase price,
return_url: <confirm url>,
cancel_return_url: <cancel url>,
items: [
{
name: 'My Item',
quantity: 1,
description: "My Item Description",
amount: price
}
]
redirect_to gateway.redirect_url_for(response.token)
This works, I can sign in as a sandboxed buyer and confirm the payment, which brings me back to <confirm url> from above. In the confirmation, I do:
response = gateway.recurring price, nil,
token: params[:token],
period: 'Year',
frequency: 1,
start_date: Time.now,
description: 'My Item Subscription'
When I do this, I receive an invalid token error from Paypal in the response variable. The token seems to be fine, it is present in the URL when I am brought back to the confirmation URL. I'm then taking it directly (params[:token]) and sending it back to Paypal.
Am I doing something completely wrong? Like I said, it seems like a lot of the documentation for this type of process is outdated (or maybe what I am trying is the stuff that is outdated...)
After looking through the source code for ActiveMerchant's Paypal express checkout gateway, I came to the conclusion that it's simply outdated when dealing with recurring payments. I switched to the paypal-recurring gem instead and everything worked fine.

Omniauth-facebook: retrieve user location

I have the following configuration in my config/initializers/omniauth.rb
provider :facebook, id, secret, {scope: 'email, user_location, user_birthday', image_size: {width: 400, height: 400}}
But the authentication hash does NOT come with user's location information.
I followed the guides and read facebook's documentation, but can't figure out whats wrong. Are there any missing steps?
Does anybody know?
Adding user location to your scope just means your app has the rights to read the user's location. It doesn't mean FB will send it to you. You need to make an FB API call to find it. Check out the Koala gem -- initialize it with the access_token you get from login and then call FB to find the location.
use 'Koala' gem for Request Graph API
and Request with '/me/location'
You must specify exactly which fields should be returned when getting the user's info.
It can be done with info_fields parameter
provider :facebook, id, secret, {
scope: 'email, user_location, user_birthday',
image_size: {width: 400, height: 400},
info_fields: 'email, name, location'
}

Issues with extracting Facebook Omniauth Authentication uid on Rails 3.1

I'm trying to extract and save in my db, the uid of a Facebook user's Omniauth Authentication.
When I issue the command user.authentications, the resulting array is displayed:
[ < Authentication id: 3, user_id: 63, provider: "facebook", uid: "123456789", created_at: "2012-07-02 02:10:48", updated_at: "2012-07-02 02:10:48" > ]
But when I execute user.authentications.last, to get the above Authentication out of the 1 item array, I receive:
< Authentication:0x007f837d32e288 >
Why doesn't it display all the parameters, id, user_id, provider, uid, etc. I can't access and extract the uid this way. I'm trying to run user.authentications.last.uid.
Thank you
What you see here is simply different string representation of the objects. Array's to_s method gives you a nice printout, but Authentication's to_s does not. Try user.authentications.last.inspect if you just want to look at it.

Resources