Rails:Omniauth使用Devise登录后从Facebook检索图像 [英] Rails: retrieving image from Facebook after Omniauth login with Devise
问题描述
我使用Devise和omniauth设置了Facebook登录,并附上了这些说明。 https:// github。 com / plataformatec / devise / wiki / OmniAuth:-Overview
Devise wiki给出了从存储在此变量中的哈希数据获取Facebook信息的一些说明 request.env ['omniauth.auth']
查看哈希的底部。
例如,Devise wiki有这两个 User.rb
模型的方法
def self.find_for_facebook_oauth(access_token ,signed_in_resource = nil)
data = access_token.extra.raw_info
如果user = User.where(:email => data.email).first
用户
else#创建具有存根密码的用户。
User.create!(:email => data.email,:password => Devise.friendly_token [0,20])
end
end
def self.new_with_session(params,session)
super.tap do | user |
if data = session [devise.facebook_data]&& session [devise.facebook_data] [extra] [raw_info]
user.email = data [email]
end
end
结束
所以,使用下面的哈希,我添加了以下两个方法来获取名称和图像
def self.find_for_facebook_oauth(access_token,signed_in_resource = nil)
data = access_token.extra.raw_info
如果user = User.where(:email => data.email).first
user
else#创建具有存根密码的用户。
User.create!(:email => data.email,:password => Devise.friendly_token [0,20],:name => data.name,:image => access_token.info。图像)#I根据第一个答案添加access_token.info.image
end
end
def self.new_with_session(params,session)
super.tap do |用户|
if data = session [devise.facebook_data]&& session [devise.facebook_data] [extra] [raw_info]
user.email = data [email]
user.name = data [name]
user.image = access_token.info.image #i根据以下第一个答案更改了这个
end
end
end
然后在我看来,我添加了以下内容以显示用户名和图像
< p>名称:<%= user.name%>< / p>
< p>图像:<%= image_tag user.image%>
但是,只有名称显示。没有图像。
在我的数据库中,我有一个名称
和图像
列。 Facebook的名称正在被存储,但是图像列表示nil
任何想法如何使图像工作?
session [devise.facebook_data ] = env [omniauth.auth]。except('extra')
I setup Facebook login with Devise and omniauth with these instructions https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
The Devise wiki gives some instructions for getting facebook info from the hash stored in this variable request.env['omniauth.auth']
See bottom for the hash.
For example, Devise wiki has these two methods for the User.rb
model
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token.extra.raw_info
if user = User.where(:email => data.email).first
user
else # Create a user with a stub password.
User.create!(:email => data.email, :password => Devise.friendly_token[0,20])
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"]
end
end
end
So, using the hash below, I added the following to those two methods to get the name and image
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token.extra.raw_info
if user = User.where(:email => data.email).first
user
else # Create a user with a stub password.
User.create!(:email => data.email, :password => Devise.friendly_token[0,20], :name => data.name, :image => access_token.info.image) #I added access_token.info.image based on first answer
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"]
user.name = data["name"]
user.image = access_token.info.image #i changed this based on first answer below
end
end
end
Then in my view, I added the following to show the user name and image
<p>Name:<%= user.name %></p>
<p>Image: <%= image_tag user.image %>
However, only the name is showing. No image.
In my database, I have a name
and an image
column. The name from Facebook is being stored, but the image column says 'nil'
Any ideas how I can get the image to work?
Hash stored in request.env['omniauth.auth']
https://github.com/mkdynamic/omniauth-facebook/blob/master/lib/omniauth/strategies/facebook.rb#L31-47
info do
prune!({
'nickname' => raw_info['username'],
'email' => raw_info['email'],
'name' => raw_info['name'],
'first_name' => raw_info['first_name'],
'last_name' => raw_info['last_name'],
'image' => "#{options[:secure_image_url] ? 'https' : 'http'}://graph.facebook.com/#{uid}/picture?type=square",
'description' => raw_info['bio'],
'urls' => {
'Facebook' => raw_info['link'],
'Website' => raw_info['website']
},
'location' => (raw_info['location'] || {})['name'],
'verified' => raw_info['verified']
})
end
The image can be found at env["omniauth.auth"]["info"]["image"]
. So in your case, access_token.info.image
.
If you want to take a good look at the hash of nested hashes returned and see for yourself where everything is, put this as the first line of your callback controller:
render :text => "<pre>" + env["omniauth.auth"].to_yaml and return
EDIT: Ok, so here's what you need to do:
def self.find_for_facebook_oauth(omniauth)
if user = User.find_by_email(omniauth.info.email)
if omniauth.info.image.present?
user.update_attribute(:image, omniauth.info.image)
end
user
else # Create a user with a stub password.
User.create!(:email => omniauth.info.email,
:name => omniauth.info.name,
:image => omniauth.info.image,
:password => Devise.friendly_token[0,20])
end
end
As for the other method, if I'm not mistaken, it should look like this:
def self.new_with_session(params, session)
super.tap do |user|
if omniauth = session["devise.facebook_data"]
user.email = omniauth.info.email
user.name = omniauth.info.name
user.image = omniauth.info.image
end
end
end
But when is this method used? It's used by Devise when something goes wrong when creating your user. Imagine that the authentication provider doesn't give you an email (Twitter, for example, does this), what can you do? Well, you can redirect the user to your sign up page where he can complete the signup process. But if you redirect the user, you lose the data received by the oauth. The solution is to put this data into the session.
So in your controller, you should have something like:
if user.save
sign_in_and_redirect user, :event => :authentication
else
session["devise.facebook_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
Another problem, however, is that most of the times the data returned by the authentication provider is too big to fit in the session, so we have to pick exactly what we want to put in the session. Since you are only getting a name and an image, you can trim the extra info like so:
session["devise.facebook_data"] = env["omniauth.auth"].except('extra')
这篇关于Rails:Omniauth使用Devise登录后从Facebook检索图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!