Omniauth没有回应GET请求

时间:2014-06-08 00:25:16

标签: ruby-on-rails devise omniauth

我正在尝试为用户提供通过Facebook登录的选项。

我的身份验证由Devise管理,我正在使用Omniauth-Facebook gem。

当我尝试在我的设计视图(session / new.html.erb)中通过Facebook登录用户时,用户已成功登录。

new.html.erb

<div><%= link_to image_tag('facebook_login.png'), user_omniauth_authorize_path(:facebook) %></div>

然而,当我尝试在不同的控制器中登录用户时(使用与上面完全相同的代码),该页面并没有真正响应,我在日志中遇到以下请求:

Started GET "/users/auth/facebook" for 127.0.0.1 at 2014-06-07 21:14:41 -0300
I, [2014-06-07T21:14:41.311370 #4592]  INFO -- omniauth: (facebook) Request phase initiated. 

Devise是否仅允许用户通过单个控制器登录facebook,还是需要对link_to路径进行其他更改?

1 个答案:

答案 0 :(得分:2)

我认为你将omniauth与devise(在omniauth初始化器中)分开配置,但仍然使用devise for login(设计omniauth的路径)。

我留下了让它与设计工作流程一起工作的步骤

<强>的Gemfile

gem 'devise'
gem 'omniauth-facebook'

<强>配置/初始化/ devise.rb

//add this for tell devise the omniauth configuration for facebook
config.omniauth :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_SECRET']

<强>配置/ enviroments / development.rb

//your secrets for development, is useful have it this way because you can use different applications for your rails enviroments
ENV['FACEBOOK_APP_ID'] = 'xxxxxxxxxxx';
ENV['FACEBOOK_SECRET'] = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

<强>的routes.rb

//override the controller for omniauth callbacks, we will define this later, this is our custom behavior for dealing with what omniauth hash will return to us
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }

好的,这是基本的,现在我们需要自定义回调来定义如何处理facebook给我们的信息。

我没有这方面的工作示例,我的回调实际上非常复杂,因为有很多行为,但我会尝试通过内存来解释。

Facebook和所有omniauth策略将返回 uid ,我们将通过提供商和他的 uid 识别我们的用户(用户ID),所以我们要将这个参数添加到我们的用户模型并执行相应的迁移,这些都是字符串

rails g migration AddOmniauthToUsers uid provider
rake db:migrate

下一步是配置我们的omniauth回调

controllers / users / omniauth_callbacks_controller.rb (请注意,它位于新用户文件夹中)

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  //this inheritance from Devise::OmniauthCallbacks so we will have all his methods 

  #uncomment the next line to see the hash from facebook, utile for debugging to see if we are getting a connection to facebook or not.
  #raise request.env["omniauth.auth"].to_yaml
  def all
    user = User.from_omniauth(request.env["omniauth.auth"])
    if @user.persisted?
       sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
       flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => user.provider.titleize
    else
        session["devise.user_attributes"] = request.env["omniauth.auth"] #create a cookie with omniauth hash to give it another try, for example in a already register email
       redirect_to new_user_registration_url
    end 
  end

  //alias method is for have the same method for various strategies(google, twitter, etc)
  alias_method :facebook, :all
end

基本上,当我们点击facebook连接时,我们得到所有omniauth参数的哈希 request.env [“omniauth.auth”] ,现在我们需要定义 from_omniauth 用于处理用户模型

的方法

<强>模型/ user.rb

def self.from_omniauth(auth)
  where(auth.slice(:provider, :uid)).first_or_create do |user|
    user.provider = auth.provider
    user.uid = auth.uid
    user.email = auth.info.email
  end
end

def self.new_with_session(params, session)
  if session["devise.user_attributes"]
    new(session["devise.user_attributes"], without_protection: true) do |user|
      user.attributes = params
      user.valid?
    end
  else
    super
  end
end

def password_required?
  super && self.provider.blank?
end

def update_with_password(params, *options)
  if encrypted_password.blank?
    update_attributes(params, *options)
  else
    super
  end
end

def has_no_password?
  self.encrypted_password.blank?
end

这里我们有4个新方法, from_omniauth 将使用hash 中的omniauth参数创建一个新用户(你可以在omniauth facebook gem中看到facebook的omniauth哈希),在这里你应该保存另一个值,如image_link或username,如果你有你的用户模型,我想从这里调用另一个模型user_profile,所有这些数据都试图让他自己的东西设置。

接下来我们有一个新的会话,它使用我们保存的cookie的内容,以防我们的回调出错

password_required? update_with_password 都是我们需要覆盖的设计方法,这个方法使用omniauth提供程序获取我们的新行为并且没有定义密码,你可以在表单中使用 has_no_password?,以便在需要时显示密码字段(更新没有密码的用户属性)。

我希望它有所帮助,当你理解工作流程很容易定制行为时,但遗憾的是大多数指南只是让你复制粘贴代码。