使用`无法找到路径的有效映射'来设计omniauthable break Omniauth身份验证

时间:2011-12-20 14:36:33

标签: ruby-on-rails ruby devise omniauth

在我的项目中,我有两种类型的用户:求职者和招聘经理。求职者没有模特,他们只能使用从第三方提供商处收到的数据申请工作,同时通过Omniauth进行身份验证。招聘经理的信息存储在设计用户模型中。招聘经理还必须能够使用其公司的Google电子邮件帐户登录。 所以,首先我使用Omniauth 1.0.0,Rails 3.1.3建立了求职者的身份验证:

omniauth.rb

require 'omniauth-openid'
require 'openid/store/filesystem'
Rails.application.config.middleware.use OmniAuth::Builder do
   provider :openid, :store => OpenID::Store::Filesystem.new('./tmp'), :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id'
   provider :facebook, "xxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  {:scope => 'email, offline_access, publish_stream', :client_options => {:ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}}}
   provider :twitter, "xxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
   provider :linkedin, "xxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxx"
 end
routes.rb中的

match '/auth/:provider/callback', :to => 'sessions#authenticate_jobseeker'
match '/auth/failure', :to => 'sessions#failure'
sessions_controller.rb

中的

def authenticate_jobseeker
  session[:jobseeker] = request.env['omniauth.auth']

  if valid_job_seeker?
    redirect_to new_job_application_path(...)
  else
    redirect_to request.env['omniauth.origin'] || root_path, alert: "Authentication failure"
  end
end

到目前为止一切正常。但是,当我开始为用户模型实施Google登录并添加:omniauthable to it时,我的求职者身份验证失败了。我正在使用Devise 1.5.2:

user.rb

class User < ActiveRecord::Base
  #...
  devise :database_authenticatable, :registerable,
         ... :lockable, :omniauthable
  #...
end
devise.rb中的

config.omniauth :open_id, :store => OpenID::Store::Filesystem.new('./tmp'), :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id', :require => 'omniauth-openid'
routes.rb中的

devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" } do
  get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
end

此时,用户的身份验证工作正常,但求职者却没有。搜索一段时间后,通过向:path_prefix => "/auth"中的每个提供商添加omniauth.rb来解决问题。 现在唯一的问题是求职者不允许访问其数据(即按“不允许”并返回应用程序),我得到每个提供者的RuntimeError:

Could not find a valid mapping for path "/auth/twitter/callback" 
Parameters:
{"denied"=>"mKjVfMRwRAN12ZxQ9cxCoD4rYSLJIRLnEqgiI"}

追踪的顶部:

devise (1.5.2) lib/devise/mapping.rb:48:in `find_by_path!'
devise (1.5.2) lib/devise/omniauth.rb:17:in `block in <top (required)>'
omniauth (1.0.0) lib/omniauth/strategy.rb:418:in `call'
omniauth (1.0.0) lib/omniauth/strategy.rb:418:in `fail!'
omniauth-oauth (1.0.0) lib/omniauth/strategies/oauth.rb:63:in `rescue in callback_phase'
omniauth-oauth (1.0.0) lib/omniauth/strategies/oauth.rb:45:in `callback_phase'
omniauth (1.0.0) lib/omniauth/strategy.rb:200:in `callback_call'
omniauth (1.0.0) lib/omniauth/strategy.rb:166:in `call!'
omniauth (1.0.0) lib/omniauth/strategy.rb:148:in `call'
omniauth (1.0.0) lib/omniauth/strategy.rb:168:in `call!'
omniauth (1.0.0) lib/omniauth/strategy.rb:148:in `call'
omniauth (1.0.0) lib/omniauth/strategy.rb:168:in `call!'
omniauth (1.0.0) lib/omniauth/strategy.rb:148:in `call'
omniauth (1.0.0) lib/omniauth/builder.rb:30:in `call'

我一直试图解决它一段时间。任何帮助是极大的赞赏。如果我能提供更多信息,请告诉我。

2 个答案:

答案 0 :(得分:1)

回答我自己的问题。因此,最终的决定是采用纯粹的Omniauth实现。我从:omniauthable模型中移除了User,从config.omniauth...移除了devise.rb,从:omniauth_callbacks移除了routes.rb设计路线。 因此,所有用户(无论是什么角色)都会使用ame回调路由并点击sessions_controller#authenticate_jobseeker操作(应考虑重命名操作?):

def authenticate_jobseeker
  auth_hash = request.env['omniauth.auth']

  unless auth_hash.present?
    redirect_to request.env['omniauth.origin'] || root_path, alert: "Sorry, we were not able to authenticate you" and return
  end

  @user = User.find_from_oauth(auth_hash)
  if @user.present?
    flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
    sign_in_and_redirect @user, :event => :authentication and return
  else
    session[:jobseeker] = auth_hash["info"]
    if valid_job_seeker?
      redirect_to new_job_application_path(...)
    end
  end
end

User.find_from_oauth

def self.find_from_oauth(auth_hash)
  if auth_hash
    user = User.where(:email => auth_hash["info"]["email"]).first
  end
  user
end

此实施满足所有要求。

答案 1 :(得分:0)

你在某个地方的模特中使用omniauth [“user_info”]吗?就我而言,我正在访问

omniauth["user_info"]["email"] 

然后会崩溃,我会得到同样的错误,被设计捕获。

在我的应用程序中,我们直接使用omniauth(针对商家)以及使用device + facebook进行用户登录。

尽管如此,还没有想到不会被设计抓住。 Devise注册它自己的失败应用程序。当我想出来时会更新。

更新:对不起,我似乎误读了你的部分问题。您可以看到从远程webapp授权的明显失败,这似乎是填充而不是代码中的掩码异常(就像我的情况一样)。