Rails:在Omniauth使用Devise登录后从Facebook检索图像

我使用这些说明设置Facebook使用Devise和omniauth登录https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview

Devise wiki提供了一些说明,用于从存储在此变量request.env['omniauth.auth']的哈希获取facebook信息。请参阅底部的哈希值。

例如,Devise wiki为User.rb模型提供了这两种方法

 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 

因此,使用下面的哈希,我将以下两个方法添加到以获取名称和图像

 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 

然后在我看来,我添加了以下内容来显示用户名和图像

 

Name:

Image:

但是,只显示名称。 没有图像。

在我的数据库中,我有一个name和一个image列。 Facebook的名称正在存储,但图片列显示’nil’

任何想法如何让图像工作?

存储在 request.env['omniauth.auth'] 哈希 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 

该图像可以在env["omniauth.auth"]["info"]["image"] 。 所以在你的情况下, access_token.info.image

如果你想好好看一下返回的嵌套哈希的哈希,看看自己的位置是什么,把它作为回调控制器的第一行:

 render :text => "
" + env["omniauth.auth"].to_yaml and return

编辑:好的,所以这是你需要做的:

 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 

至于另一种方法,如果我没有弄错,它应该是这样的:

 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 

但是这个方法何时使用? 在创建用户时出现问题时,Devise会使用它。 想象一下,身份validation提供程序没有给你发电子邮件(例如Twitter,这样做),你能做什么? 好吧,您可以将用户重定向到您可以完成注册过程的注册页面。 但是,如果您重定向用户,则会丢失oauth收到的数据。 解决方案是将此数据放入会话中。

所以在你的控制器中,你应该有类似的东西:

 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 

然而,另一个问题是,大多数情况下,身份validation提供程序返回的数据太大而无法容纳在会话中,因此我们必须准确选择要在会话中放入的内容。 由于您只获取名称和图像,因此您可以修改额外信息,如下所示:

 session["devise.facebook_data"] = env["omniauth.auth"].except('extra')