Разработать всевозможные разрывы Аутентификация Omniauth с помощью «Не удалось найти правильное сопоставление для пути» - PullRequest
3 голосов
/ 20 декабря 2011

В моем проекте есть два типа пользователей: соискатели и менеджеры по найму.Соискатели не имеют модели, они просто могут подать заявку на работу, используя данные, полученные от сторонних поставщиков при аутентификации через Omniauth.Информация менеджеров по найму хранится в модели пользователя devise.Менеджеры по найму также должны иметь возможность войти в систему с учетной записью электронной почты 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'

in 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 для модели User и добавил: omniauthable к нему, моя проверка подлинности соискателя прервалась.Я использую 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 ]

1 голос
/ 13 января 2012

Отвечая на мой собственный вопрос. Итак, окончательное решение состояло в том, чтобы пойти с чистой реализацией 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

Эта реализация удовлетворяет всем требованиям.

0 голосов
/ 12 января 2012

Вы где-нибудь используете omniauth ["user_info"] в своих моделях?В моем случае я обращался к

omniauth["user_info"]["email"] 

, и это приводило к сбою, и я получал ту же ошибку, когда меня ловило устройство.

В моем приложении мы также напрямую используем omniauth (для бизнеса), а также использовать устройство + facebook для входа в систему.

Пока еще не понял, чтобы не получить отказ поймал устройство.Разработать регистрирует свое собственное приложение сбоя.Обновлюсь, когда я это выясню.

Обновление: извините, кажется, я неправильно прочитал часть вашего вопроса.Вы можете видеть явный сбой авторизации из удаленного веб-приложения, которое кажется заполненным, а не замаскированным исключением из кода (как было в моем случае).

...