Facebook Omniauth login not returning all fields - ruby-on-rails

I'm setting up the Facebook provider as follows:
provider :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET'], scope: ['email', 'public_profile']
The authorization appears to work fine, in that the Facebook dialog mentions the relevant requested permissions, but I'm only getting name and picture details coming back to the callback URL. The omniauth.auth hash looks as follows:
{
"provider":"facebook",
"uid":<redacted>
"info":{
"name":<redacted>,
"image":<redacted>,
"credentials":{
"token":<redacted>,
"expires_at":1442319308,
"expires":true
},
"extra":{
"raw_info":{
"name":<redacted>,
"id":<redacted>
}
}
}
Shouldn't I be seeing more fields here?

I had the exact same problem. You've probably figured this out, but in case you haven't... You just need to make sure to edit Devise.rb in addition to Omniauth.rb
Devise.rb should have:
config.omniauth :facebook, "your_facebook_id", "your_facebook_secret", scope: 'email,public_profile', info_fields: 'email, first_name, last_name'
replacing whatever specific info_fields you need (list of all available here)

Related

How do I use omniauth in RoR to extract Facebook birthday information?

I’m using Rails 4.2.7 with Omniauth 1.3.1. When someone logs into my app using Facebook, I’d like to record their birthday, however, I can’t figure out how to extract it from Facebook’s site when I got my auth object. I have this in my config/initializers/omniauth.rb file …
Rails.application.config.middleware.use OmniAuth::Builder do
…
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'],
scope: 'public_profile', info_fields: 'id,email,link,birthday,first_name,last_name'
but once my callback is returned to my application ..
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
The call dies because there is no birthday to extract …
def self.from_omniauth(auth)
puts "extra: #{auth.extra}"
bday = Date.strptime(auth.extra.raw_info.birthday,'%m/%d/%Y')
What is printed out in “extra:” is
extra: #<OmniAuth::AuthHash raw_info=#<OmniAuth::AuthHash first_name=“MyName” id="1777736954079999” last_name=“LastName” link="https://www.facebook.com/app_scoped_user_id/1777736954079999/">>
even though I definitely have a birthday set up in my Facebook profile. What else do I need to do to pass/extract the birthday information?
According with Facebook's Login documentation, the permission for public_profile doesn't include birthday information, but only the following fields: id, name, first_name, last_name, age_range, link, gender, locale, picture, timezone, updated_time, verified.
The user_birthday permission will give you access to date and month of a person's birthday. They also state that it may or may not include the year.
Try adding user_birthday to your scope.
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'],
scope: 'public_profile,user_birthday', info_fields: 'id,email,link,birthday,first_name,last_name'

How to specify app_secret for a Koala object?

In devise.rb
config.omniauth :facebook, app_id, 'app_secret', :scope => 'email', info_fields: 'email, name, address, birthday, age_range, first_name, gender, hometown, location '
In user.rb (model)
def facebook
#facebook ||= Koala::Facebook::API.new(self.oauth_token)
end
The oauth token for the user object is set and then the following is called.
user.facebook.get_object("me")
This is the response
{"name"=>"name", "id"=>"uid"}
I do not get any additional information like address, email, image link etc, although, if the user is made to sign in via omniauth-facebook, I get all the params. What should I do?
It's because each user has certain things restricted or granted by default, their security settings. Oauth, bumps the user and says "if you want access to this app, you'll need to agree to let us have these permissions on your account" -- the user says ok and you get the info you need. Users with certain security settings will also let you see other about-me info.
So... the simple answer is to use an oauth login. that will ensure the token you get back gives you access to the things you list in the scope.
Out of curiosity, is there a reason you aren't asking for oauth login already?

Set different facebook oauth scope per user with devise

I have a rails app with two separate types of users (call them A and B). Right now they can both sign in with facebook. However, I need B to be able to oauth with some extended permissions, and I DO NOT want A to give me the extended permissions.
Inside config/initializers/devise.rb
config.omniauth :facebook, "API_KEY", "API_SECRET", :client_options => {:ssl => {:ca_path => ' /path/to/my/ssl/stuff'}}
I know I can add
:scope => "extended_permissions"
But I only want the extended permissions to happen when B users sign up.
Since this is in an initializer is this even possible? Or can I somehow config.omniauth elsewhere in the app and keep devise happy?
It's clearly explained in the documentation
If you want to set the display format, auth_type, or scope on a
per-request basis, you can just pass it to the OmniAuth request phase
URL, for example: /auth/facebook?display=popup or
/auth/facebook?scope=email.
source: https://github.com/mkdynamic/omniauth-facebook#per-request-options

Why does Google OAuth2 authentication fail when using analytics url instead of youtube url?

I'm working on a dashboard for my colleagues that shows a few stats from Google Analytics next to some other statistics. To get access to the Analytics data I use OAuth2. OAuth2 requires a scope to get send along with the authentication request in order to get access tokens. I created a client ID in the APIs Console that has access to Analytics, and specify the scope in an initializer that looks like this:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['ADMIN_DASHBOARD_GOOGLE_CLIENT_ID'], ENV['ADMIN_DASHBOARD_GOOGLE_CLIENT_SECRET'], { access_type: 'online', approval_prompt: '', scope: 'http://gdata.youtube.com,userinfo.email,userinfo.profile,analytics.readonly' }
end
This uses the omniauth-google-oauth2 gem, and the scope I found in an example somewhere. However, for my implementation, I think this scope is strange. Instead of http://gdata.youtube.com,userinfo.email,userinfo.profile,analytics.readonly I would like to use https://www.googleapis.com/auth/analytics.readonly, but changing to that scope causes the request to return invalid_credentials. What is the correct way to specify only access to analytics data is needed?
Scopes should be seperated by a space character, not a comma:
https://developers.google.com/accounts/docs/OAuth2WebServer#formingtheurl
if you need Youtube and Analytics scopes use:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['ADMIN_DASHBOARD_GOOGLE_CLIENT_ID'], ENV['ADMIN_DASHBOARD_GOOGLE_CLIENT_SECRET'], { access_type: 'online', approval_prompt: '', scope: 'http://gdata.youtube.com,userinfo.email https://www.googleapis.com/auth/analytics.readonly' }
end
if you need just Analytics, use:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['ADMIN_DASHBOARD_GOOGLE_CLIENT_ID'], ENV['ADMIN_DASHBOARD_GOOGLE_CLIENT_SECRET'], { access_type: 'online', approval_prompt: '', scope: 'https://www.googleapis.com/auth/analytics.readonly' }
end

OmniAuth using google oauth 2 strategy scope failure

I'm working on getting calendar data from google using OmniAuth and the google-oauth-2 strategy.
If I put nothing into the scope field it works fine and I get the default info without the auth/failure message and I can use the app normally.
However the moment I add a scope, as in the example below, I get an "auth/failure?message=invalid_credentials".
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['TEST_KEY'], ENV['TEST_SECRET'], { :scope => 'https://www.google.com/calendar/feeds/' }
end
Is there something I'm missing or something I should change?
A quick e-mail from the google-oauth-2 strategy author pointed out the following:
If you don't include the profile scopes, it fails to authenticate.
By adding userinfo.email and userinfo.profile (along with the calendar scope) to the comma separated :scope list I was able to fix the problem.
Example:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['TEST_KEY'], ENV['TEST_SECRET'],
{ :scope => 'userinfo.email, userinfo.profile, https://www.googleapis.com/auth/calendar' }
end
Funny, this didn't work for me.
I was able to make it work, removing the comma from the scope:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['TEST_KEY'], ENV['TEST_SECRET'],
{ :scope => 'https://www.googleapis.com/auth/docs https://www.googleapis.com/auth/userinfo.profile' }
end

Resources