Rails: Using OmniAuth (FB authorization), Reading

2019-09-15 04:06发布

问题:

Using OmniAuth, I successfully fetched the hash data from Facebook: stored in "auth"

# extra=#] last_name="Jordan" link="http://www.facebook.com/michael" locale="en_US" middle_name="Ball" name="Michael Jordan" quotes="\"lalala\"\n\n\"lala\"" timezone=9 updated_time="2011-09-01T20:25:58+0000" username="mjordan82" verified=true>> info=# verified=true> provider="facebook" uid="123456879">

In User Model, I do as follows:

def self.create_with_omniauth(auth)
  create! do |user|
    user.provider = auth["provider"]
    user.uid = auth["uid"]
    user.name = auth["name"]
  end
end

When I checked the database, I only got provider and uid. User.name row was empty. From testing, I figured out I couldn't store other data than provider and uid. For example, user.name = auth["provider"] or user.name = auth["uid"] stored with no problem, but when I tried something like user.name = auth["timezone"] or user.name = auth["last_name"], nothing was stored in the variable. Anyone know how to fix this? I also tried user.name = auth["user_info"]["name"], but it returned an error.

I am not sure why user.name = auth["name"] does not store anything. In other words, why is auth["name"] not "Michael Jordan" in this case?

回答1:

The key was this: I was accessing the auth hash in a wrong way. The answer is you do

user.name = auth["info"]["name"]

Here's detailed information about the Auth Hash:

:provider => 'facebook',
:uid => '1234567',

:info => {
 :nickname => 'jbloggs',
 :email => 'joe@bloggs.com',
 :name => 'Joe Bloggs',
 :first_name => 'Joe',
 :last_name => 'Bloggs',
 :image => 'http://graph.facebook.com/1234567/picture?type=square',
 :urls => { :Facebook => 'http://www.facebook.com/jbloggs' },
 :location => 'Palo Alto, California',
 :verified => true
},
:credentials => {
 :token => 'ABCDEF...', # OAuth 2.0 access_token, which you may wish to store
 :expires_at => 1321747205, # when the access token expires (it always will)
 :expires => true # this will always be true
},
:extra => {
  :raw_info => {
  :id => '1234567',
  :name => 'Joe Bloggs',
  :first_name => 'Joe',
  :last_name => 'Bloggs',
  :link => 'http://www.facebook.com/jbloggs',
  :username => 'jbloggs',
  :location => { :id => '123456789', :name => 'Palo Alto, California' },
  :gender => 'male',
  :email => 'joe@bloggs.com',
  :timezone => -8,
  :locale => 'en_US',
  :verified => true,
  :updated_time => '2011-11-11T06:21:03+0000'
}

source: https://github.com/mkdynamic/omniauth-facebook

This is why I could access "provider" and "uid" with simply auth["provider"], and I needed to do

auth["info"]["name"] 

to access the name information.

Similarly, to get the user's timezone, you could do

auth["extra"]["timezone"]