Omniauth不响应GET请求 [英] Omniauth not responding to GET Request

查看:93
本文介绍了Omniauth不响应GET请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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



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



new.html.erb

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

然而,当我尝试使用不同的控制器登录用户(使用与上述完全相同的代码)页面没有真正的回应,我被卡在以下请求在我的日志:

 开始GET/用户/ auth / facebookfor 127.0.0.1在2014-06-07 21:14:41 -0300 
I,[2014-06-07T21:14:41.311370#4592] INFO - omniauth:(facebook)要求阶段启动。

Devise只允许用户通过单个控制器登录Facebook,或有其他更改我需要做link_to路径?

解决方案

我认为你配置omniauth独立于devise(在全能初始化器),但仍然使用设计登录(omniauth的设计路径)。



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



Gemfile

  gem'devise'
gem'omniauth-facebook'

配置/ initializers / devise.rb

  //添加这个为tell设计omniauth配置为Facebook 
config.omniauth:facebook,ENV ['FACEBOOK_APP_ID'],ENV ['FACEBOOK_SECRET' ]

config / enviroments / development.rb

  //你的秘密开发,是有用的这个方式,因为您可以使用不同的应用程序为您的轨道环境
ENV ['FACEBOOK_APP_ID'] ='xxxxxxxxxxx';
ENV ['FACEBOOK_SECRET'] ='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

routes.rb

  //覆盖控制器的omniauth回调,我们稍后将定义,这是我们的自定义行为来处理什么Omniauth哈希将返回给我们
devise_for:users ,控制器:{omniauth_callbacks:users / omniauth_callbacks}

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



我没有一个工作的例子,我的回调其实是真的复杂因为有很多行为,但我会尝试通过记忆来解释。



Facebook和所有的全方位策略将返回一个 uid ,我们是将通过提供者和他的 uid (用户ID)识别我们的用户,所以我们将把这个参数添加到我们的用户模型中相应的迁移,这些都是 strin gs

  rails g migration AddOmniauthToUsers uid provider 
rake db:migrate

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



控制器(请注意在新的用户文件夹中)



  class Users :: OmniauthCallbacksController< Devise :: OmniauthCallbacksController 
//这个来自Devise :: OmniauthCallbacks的这个继承,所以我们将会有所有的方法

#uncomment下一行,从脸书看到哈希,我们正在与Facebook取得联系。
#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 => :认证#如果@user没有被激活,则会抛出
flash [:notice] = I18n.tdevise.omniauth_callbacks.success,:kind => user.provider.titleize
else
session [devise.user_attributes] = request.env [omniauth.auth]#创建一个带有omniauth哈希的cookie,以便再次尝试,例如在已经注册电子邮件
redirect_to new_user_registration_url
end
end

// alias方法是针对各种策略(google,twitter等)使用相同的方法
alias_method:facebook,,all
end

基本上,当我们点击Facebook连接时得到这个哈希 request.env [omniauth.auth] 与所有的omniauth参数,现在我们需要定义我们的 from_omniauth 方法来处理我们的用户模型



models / user.rb

 $ code def self.from_omniauth(auth)
其中(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)
如果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?
超级&& self.provider.blank?
end

def update_with_password(params,* options)
如果encrypted_pa​​ssword.blank?
update_attributes(params,* options)
else
super
end
end

def has_no_password?
self.encrypted_pa​​ssword.blank?
end

这里我们有4种新方法, from_omniauth 创建一个新的用户与omniauth参数从哈希(你可以看到omniauth的Facebook的宝石的脸书的omniauth哈希),在这里你应该保存另一个值,如image_link或用户名,如果你有你的用户模型我喜欢从这里再次打电话给user_profile,所有这些数据都是试图用自己的东西去设计。



接下来我们有新的会话,使用内容我们保存的cookie在我们的回调中出现错误



password_required? update_with_password 都是设计方法我们需要覆盖,这个抓住了我们对omniauth提供者的情况的新行为,没有定义密码,你可以在窗体中使用 has_no_password?,只需在需要时显示密码字段(更新用户属性没有密码)。



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


I am trying to enable users with the option to signing in through Facebook.

My authentication in managed by Devise and I'm using the Omniauth-Facebook gem.

When I try to login the user through Facebook in my devise views (session/new.html.erb), the user is logged in successfully.

new.html.erb

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

However when I try to sign in the user in a different controller (using the exactly same code as above) the page doesn't really respond and I'm stuck with the following request on my log:

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. 

Does Devise only allow users to sign in with facebook through a single controller or is there some other change I need to make to the link_to path?

解决方案

I think you configure omniauth separate from devise(in omniauth initializers), but still using devise for login(devise paths for omniauth).

I leave the steps for get it working with devise work-flow

Gemfile

gem 'devise'
gem 'omniauth-facebook'

config/initializers/devise.rb

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

config/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" }

Ok this is the basic, now we need to have our custom callbacks that defines what to do with the information that facebook gives to us.

I don't have a working example for this, my callbacks are actually really complicated because have lots of behaviors, but i will try to explain by memory.

Facebook and all omniauth strategies will return an uid, we are gonna identify our users by the provider and his uid (user id), so we are gonna add this params to our user model and do the corresponding migrations, these are both strings.

rails g migration AddOmniauthToUsers uid provider
rake db:migrate

The next step is configure our omniauth callback

controllers/users/omniauth_callbacks_controller.rb (note that is in a new users folder)

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

Basically, when we click the facebook connection we get this hash request.env["omniauth.auth"] with all the omniauth params and now we need to define our from_omniauth method for dealing with in our user model

models/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

Here we have 4 new methods, from_omniauth will create a new user with the omniauth params from the hash (you can see the omniauth hash for facebook in omniauth facebook gem), here you should save another values like image_link or username if you have it your user model, i like to call from here another model user_profile with all these data a trying to leave devise with his own things.

Next we have new with session, that use the content of the cookie that we save in case of error in our callback

password_required? and update_with_password are both devise methods that we need to override, this one grab our new behavior for the cases with omniauth provider and no password defined, you could use has_no_password? in your forms for displaying password fields just when need it(update user attributes without a password).

I hope it helps, when you understand the work-flow is really easy to customize the behaviors, but sadly most guides just let you copy-paste the code.

这篇关于Omniauth不响应GET请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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