设计全方位休息Omniauth认证与'找不到路径的有效映射' [英] Devise omniauthable breaks Omniauth authentication with `Could not find a valid mapping for path`

查看:162
本文介绍了设计全方位休息Omniauth认证与'找不到路径的有效映射'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my project, I have two type of users: job seekers and hiring managers. Job seekers don't have a model, they are just able to apply for jobs using the data received from from third-party providers while authenticating thru Omniauth. Hiring managers' info is stored in devise User model. Hiring managers also must be able to sign in with their company's Google email account. So, first I built job seekers' authentication using 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登录用户模型,并添加了:全方位的,我的求职者身份验证破裂。我正在使用Devise 1.5.2:

Up to this point everything worked fine. However, when I started implementing Google sign on for User model, and added :omniauthable to it, my job seeker authentication broke. I am using Devise 1.5.2:

user.rb

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

in 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:

At this point, Users' authentication worked, but job seekers' did not. After searching for a while, the issue was fixed by adding :path_prefix => "/auth" to every provider in omniauth.rb. The only problem now, is when job seeker does not allow access to its data (i.e. presses "Don't Allow" and comes back to the application), I get following RuntimeError for every provider:

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'

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

I've been trying to solve it for a while now. Any help is greatly appreciated. Let me know, if I can provide additional info.

推荐答案

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

Answering my own question. So, final decision was to go with pure Omniauth implementation. I removed :omniauthable from User model, removed config.omniauth... from devise.rb, removed :omniauth_callbacks devise routes from routes.rb. So, all users (no matter what role) would use ame callback routes and hit sessions_controller#authenticate_jobseeker action (should consider renaming the action?):

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

此实现满足所有要求。

这篇关于设计全方位休息Omniauth认证与'找不到路径的有效映射'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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