“没找到。认证passthru。”错误。当它在另一个引擎内部时,Devise Omniauthable模块不起作用

时间:2014-08-06 02:16:16

标签: ruby-on-rails ruby devise rubygems omniauth

我按照本指南尝试将Devise放入另一个可安装的宝石中: How To: Use devise inside a mountable engine

除了omniauth部分外,一切似乎都正常。我正试图让omniauth-google-oauth2工作。我发现it's a known issue in Devise,但除了没有提出的解决方案有效之外,我注意到该问题中提到的解决方案has already been implemented inside Devise

这是我到目前为止所做的:

my_engine / my_engine.gemspec

s.add_dependency 'omniauth'
s.add_dependency 'devise'
s.add_dependency 'omniauth-google-oauth2'

my_engine / LIB / my_engine.rb

require 'omniauth-google-oauth2'
require 'devise'

my_engine /配置/初始化/ devise.rb

config.omniauth :google_oauth2, ENV['GOOGLE_OAUTH2_API_KEY'], ENV['GOOGLE_OAUTH2_SECRET'], scope: 'email, profile'

my_engine /配置/ routes.rb中

devise_for :users, controllers: {omniauth_callbacks: 'my_engine/omniauth_callbacks'}, class_name: "MyEngine::User", module: :devise

my_engine /应用/控制器/ my_engine / omniauth_callbacks_controller.rb

class MyEngine::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def all
    auth = request.env["omniauth.auth"]
    user = MyEngine::User.from_omniauth(request.env["omniauth.auth"])
    user.update_attributes(name: auth.info.name)
    if user.persisted?
      flash.notice = 'Signed in!'
      sign_in_and_redirect user
    else
      session["devise.user_attributes"] = user.attributes
      redirect_to new_user_registration_url
    end
  end
  alias_method :google_oauth2, :all
end

当我点击“使用Google OAuth2登录”时,它会直接转到MyEngine::OmniauthCallbacksController#passthru并输出“未找到。身份验证passthru”。我一直在挖掘源代码,但我无法弄清楚Devise如何通过提供程序方法而不是#passthru。我在这里错过了什么吗?我正在运行rails 4.1,Ruby 2.0,设计3.2.4和omniauth-oauth2 1.2.0。

2 个答案:

答案 0 :(得分:0)

我也有这个问题。我工作的版本与您链接到的github问题页面上讨论的解决方案非常相似,但不完全相同(我已经调整了我在下面的代码中稍微做了些什么,因为我还有一个自定义{{1}在我的:path中指定的。此外,我目前正在设计3.1.2但希望这与以下内容完全相似,为你工作。

my_engine / config / routes.rb

devise_for
my_engine / config / initializers / devise.rb 中的

devise_for :users, :class_name => 'MyEngine::User', :module => :devise, :controllers => { :omniauth_callbacks => "my_engine/omniauth_callbacks" }

devise_scope :user do
  # Had to add routes for callbacks here because otherwise the routes get
  # messed up -- prepending an extra "/my_engine" in one case.
  providers = Regexp.union(Devise.omniauth_providers.map(&:to_s))

  path_prefix = '/users/auth'

  match "#{path_prefix}/:provider",
    :constraints => { :provider => providers },
    :to => "omniauth_callbacks#passthru",
    :as => :user_omniauth_authorize,
    :via => [:get, :post]

  match "#{path_prefix}/:action/callback",
    :constraints => { :action => providers },
    :to => 'omniauth_callbacks',
    :as => :user_omniauth_callback,
    :via => [:get, :post]
end

其中一些可能是不必要的,但是我花了一些时间通过调试器逐步完成流程并且没有时间回去尝试使其更优雅/精益任何东西。

答案 1 :(得分:0)

我找到了更好的解决方案。更新您的lib / MyEngine / engine.rb。 使用此解决方案,您不必添加设计范围部分(我的示例仅适用于facebook)

module MyEngine
  require 'omniauth'
  require 'omniauth-facebook'

  class Engine < ::Rails::Engine
    isolate_namespace SimpleUser

    middleware.use OmniAuth::Builder do
      provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], :scope => ENV['FACEBOOK_SCOPE']
  end
end