Facebook OAuth is not returning email in user info
Asked Answered
C

3

5

I'm doing a spree 3.0 installation (ROR) and trying to use facebook oauth for authentication, but the fields sent back after a successful oauth, do NOT contain the email, which is critical to our application. here is the return from the facebook successful authentication.

#<OmniAuth::AuthHash credentials=#<OmniAuth::AuthHash expires=true expires_at=1442435073 token="CAAJa3dyBtY4BAJ2ZB3vrenNOFJKSMtvxYO09ZCJtEsmKNBs90q9nmUF4LIBr06xCizEAR3lwht3BwycLkVFdjlvkS1AUGpYODQHu25K0uO8XLDDPkTO0E9oPdIILsbTTOuIT7qcl8nJ6501z0dCXEi9hVNwPYqZBbGqiEhyoLyVgCNnDWdPRLBRF5xSovJdhjjCf6XC8ulJ4NnKBfM8"> extra=#<OmniAuth::AuthHash raw_info=#<OmniAuth::AuthHash id="101230990227589" name="David Alajbbjfdjgij Bowersstein">> info=#<OmniAuth::AuthHash::InfoHash image="http://graph.facebook.com/101230990227589/picture" name="David Alajbbjfdjgij Bowersstein"> provider="facebook" uid="101230990227589"

as you can see, all i get back is the user name and their ID. Is there some setting on my facebook app that i need to check in order to get the email back? or is there a different way i'm supposed to do Oauth? I'm just using the spree_social gem which does this all internally so i've actually not written any code around this.

here is the code. copied out of the gem, i just added the logging lines to see what was coming back from facebook.

    def #{provider}
      authentication = Spree::UserAuthentication.find_by_provider_and_uid(auth_hash['provider'], auth_hash['uid'])

      if authentication.present? and authentication.try(:user).present?
        flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: auth_hash['provider'])
        sign_in_and_redirect :spree_user, authentication.user
      elsif spree_current_user
        spree_current_user.apply_omniauth(auth_hash)
        spree_current_user.save!
        flash[:notice] = I18n.t('devise.sessions.signed_in')
        redirect_back_or_default(account_url)
      else
        user = Spree::User.find_by_email(auth_hash['info']['email']) || Spree::User.new
        user.apply_omniauth(auth_hash)
        Rails.logger.debug("THE AUTO HASH")
        Rails.logger.debug(auth_hash.inspect)
        if user.save
          flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: auth_hash['provider'])
          sign_in_and_redirect :spree_user, user
        else
          session[:omniauth] = auth_hash.except('extra')
          flash[:notice] = Spree.t(:one_more_step, kind: auth_hash['provider'].capitalize)
          redirect_to new_spree_user_registration_url
          return
        end
      end

      if current_order
        user = spree_current_user || authentication.user
        current_order.associate_user!(user)
        session[:guest_token] = nil
      end
    end
Complacency answered 19/7, 2015 at 15:57 Comment(4)
Can you share the code that you're using please? Quick note that Facebook returns nil for a FB user's email when (1) the user hasn't validated their email on FB or (2) the user is using their telephone number for logging into FB rather than email.Gladiate
code added. its copied straight from the gem except the logging statementComplacency
Have you tried one of the FB app test users? #9347604Gladiate
yes, i tested using my own account and then one of the facebook generated test users from developer section of facebook.Complacency
J
9

Facebook just released latest APIv2.4 that does not return email by default but we need to explicitly specify what fields to use.

Introducing Graph API v2.4

Now, on the very latest omniauth-facebook(possibly 2.1.0), "email" fields are specified by default and just works.

Fix default info_fields to 'name,email' #209

Or, you can just specify like

options['info_fields']='id,email,gender,link,locale,name,timezone,updated_time,verified';
Jupiter answered 22/7, 2015 at 4:49 Comment(2)
Where can i add those options?Oldham
@AymanSalah you can set it in the config.omniauth :facebook block: :info_fields => 'id,email,gender,link,locale,name,timezone,updated_time,verified'Dressy
I
0

Possibly you need to request the email permission from user to share email to your FB App.

Try to add this initilazer facebookstrategies.rb to request the specific permission to facebook.

module OmniAuth
  module Strategies
    class Facebook < OAuth2

      MOBILE_USER_AGENTS =  'palm|blackberry|nokia|phone|midp|mobi|symbian|chtml|ericsson|minimo|' +
                          'audiovox|motorola|samsung|telit|upg1|windows ce|ucweb|astel|plucker|' +
                          'x320|x240|j2me|sgh|portable|sprint|docomo|kddi|softbank|android|mmp|' +
                          'pdxgw|netfront|xiino|vodafone|portalmmm|sagem|mot-|sie-|ipod|up\\.b|' +
                          'webos|amoi|novarra|cdm|alcatel|pocket|ipad|iphone|mobileexplorer|' +
                          'mobile'
      def request_phase
        options[:scope] ||= "email,offline_access,user_birthday,public_profile"
        options[:display] = mobile_request? ? 'touch' : 'page'
       super
      end

      def mobile_request?
        ua = Rack::Request.new(@env).user_agent.to_s
        ua.downcase =~ Regexp.new(MOBILE_USER_AGENTS)
      end
    end
  end
end
Injection answered 20/7, 2015 at 7:13 Comment(1)
thanks for the effort but after inserting the code and restarting, its still the same thing. no email. exact same hash is returned, only image and name in the info section.Complacency
B
0

I had the same issue and this is how I solved it.

In config/initializers/devise.rb add following code:

Devise.setup do |config|
  config.omniauth :facebook, your_app_id, your_app_secret, scope: 'public_profile,email', info_fields: 'email,name'
end
Beale answered 8/1, 2017 at 23:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.