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

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

问题描述

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

I setup Facebook login with Devise and omniauth with these instructions https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview

Devise wiki 提供了一些说明,用于从存储在此变量中的散列中获取 facebook 信息 request.env['omniauth.auth'] 散列见底部.

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.

例如Devise wiki对于User.rb模型有这两种方法

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.

在我的数据库中,我有一个 name 和一个 image 列.正在存储来自 Facebook 的名称,但图像列显示nil"

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?

哈希存储在 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.

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

好的,这是您需要做的:

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

但是这个方法什么时候用呢?当创建用户时出现问题时,Devise 会使用它.想象一下,身份验证提供商不给您电子邮件(例如,Twitter 会这样做),您能做什么?好吧,您可以将用户重定向到您的注册页面,他可以在其中完成注册过程.但是如果你重定向用户,你会丢失 oauth 收到的数据.解决办法就是把这些数据放到session中.

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:使用 Devise 登录 Omniauth 后从 Facebook 检索图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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