ruby-on-rails - "Not found. Authentication passthru."错误。设计 Omniauthable 模块不会在另一个引擎中使用 't work when it' s

标签 ruby-on-rails ruby devise rubygems omniauth

我尝试按照本指南将 Devise 放入另一个可安装的 gem 中: 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/config/initializers/devise.rb

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

my_engine/config/routes.rb

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

my_engine/app/controllers/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 并输出“未找到。身份验证通过”。我一直在挖掘源代码,但我无法弄清楚 Devise 如何让它通过提供者方法而不是 #passthru。我在这里错过了什么吗?我在 Rails 4.1、Ruby 2.0、devise 3.2.4 和 omniauth-oauth2 1.2.0 上运行。

最佳答案

我也遇到过这个问题。我使用的版本与您链接到的 github 问题页面上讨论的解决方案非常相似,但不完全相同(我在下面的代码中稍微调整了我所做的,因为我还有一个自定义 :path 在我的 devise_for 中指定)。此外,我目前正在使用 devise 3.1.2,但希望它与以下内容足够相似以供您使用。

my_engine/config/routes.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

my_engine/config/initializers/devise.rb 中:

config.router_name = :my_engine
config.omniauth_path_prefix = "/my_engine/users/auth"

其中一些可能是不必要的,但在花了一些时间使用调试器逐步完成流程后,我让它像这样工作,并且没有时间回过头来尝试让它更优雅/精简或其他任何东西。

关于ruby-on-rails - "Not found. Authentication passthru."错误。设计 Omniauthable 模块不会在另一个引擎中使用 't work when it' s,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25151273/

相关文章:

ruby-on-rails - 什么是 Searchlogic 的可行替代品?

ruby-on-rails - 在 heroku 上运行自定义 rake 任务

ruby-on-rails - 测试 Rails 页面是否正常工作的正确方法

ruby-on-rails - 测试设计使用 Rspec 更新用户注册信息并获取:ActionController::UnknownFormat: Error

ruby-on-rails - 未定义的局部变量或方法 `encrypted_password'

ruby-on-rails - 如何跳过 ruby 中的外循环?

javascript - 来自 Google Analytics api 的 JSON 响应

ruby - 将电话号码转换成单词

ruby-on-rails - 将外部 PDF 插入到 Prawn 生成的文档中

Ruby DateTime.Parse 到本地时间