Rails:Omniauth使用Devise登录后从Facebook检索图像 [英] Rails: retrieving image from Facebook after Omniauth login with Devise

查看:121
本文介绍了Rails:Omniauth使用Devise登录后从Facebook检索图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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



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



哈希存储在 request.env ['omniauth.auth'] https://github.com/mkdynamic / / n。 info
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并返回

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

  def self.find_for_facebook_oauth(omniauth)
如果user = User.find_by_email(omniauth.info。电子邮件)
如果omniauth.info.image.present?
user.update_attribute(:image,omniauth.info.image)
end
user
else#使用存根密码创建用户。
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 |
如果omniauth = session [devise.facebook_data]
user.email = omniauth.info.email
user.name = omniauth.info.name
user.image = omniauth .info.image
end
end
end

但是这个方法是用吗?当创建用户时出现错误,Devise使用它。想象一下,身份验证提供商不会给你一个电子邮件(例如,Twitter,这样做),你能做什么?那么您可以将用户重定向到您的注册页面,在那里他可以完成注册过程。但是如果您重定向用户,则丢失由oauth接收的数据。解决方案是将这些数据放入会话中。



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

  if user.save 
sign_in_and_redirect user,:event => :验证
else
会话[devise.facebook_data] = env [omniauth.auth]
redirect_to new_user_registration_url
end
然而,另一个问题是,认证提供商返回的数据大多数时间太大,无法适应会话,因此我们必须选择正是我们想要放在会议上。由于您只是获得了一个名称和图像,所以您可以修改额外的信息:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆