2011-12-20 90 views
3

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

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,我的求职者身份验证打破了。我使用的设计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' 

我一直在试图解决它一段时间了。任何帮助是极大的赞赏。让我知道,如果我可以提供更多信息。

回答

1

回答我自己的问题。因此,最终决定是使用纯粹的Omniauth实现。我从User模型中删除了:omniauthable,从devise.rb中删除config.omniauth...,删除了:omniauth_callbacksroutes.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 

此实现满足所有的要求。

0

你是否在模型中使用了omniauth [“user_info”]?在我的情况下,我正在访问

omniauth["user_info"]["email"] 

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

在我的应用程序中,我们直接使用omniauth(用于企业)以及使用设备+ facebook用户登录。

但还没有想出失败抓住设计虽然。设计注册它自己的失败应用程序。将更新时,我知道了。

更新:我很抱歉,似乎我误解了你的问题的一部分。你可以看到明显的失败,从远程webapp授权,似乎填满了,而不是来自代码的掩盖异常(如我的情况)。

+0

考虑'omniauth [“user_info”] [“email”]''。我访问auth提供者接收的auth_hash,就像这个'request.env [“omniauth.auth”]''一样。然后我''“info”] [“email”]就可以了。虽然较新版本的设计建议使用autn_hash.info ['email']'。 – 2012-01-13 14:46:19