【问题标题】:Callback denied with OmniAuth使用 OmniAuth 拒绝回调
【发布时间】:2012-06-09 17:59:07
【问题描述】:

当我在 Rails 3 应用程序中使用 OmniAuth 启动登录过程时,如果我在提供者的页面上取消,我会被发送回一个类似于以下内容的 URL:

http://example.com/auth/twitter/callback?denied=aUho....

我的应用程序抛出一个 500,我可以看到它是 OAuth::Unauthorized: 401 Unauthorized,而我的任何控制器操作都没有触及。

堆栈跟踪是当我在我的计算机中重现它时:

oauth (0.4.6) lib/oauth/consumer.rb:216:in `token_request'
oauth (0.4.6) lib/oauth/consumer.rb:136:in `get_request_token'
omniauth-oauth (1.0.1) lib/omniauth/strategies/oauth.rb:29:in `request_phase'
omniauth-twitter (0.0.11) lib/omniauth/strategies/twitter.rb:50:in `request_phase'
omniauth (1.1.0) lib/omniauth/strategy.rb:207:in `request_call'
omniauth (1.1.0) lib/omniauth/strategy.rb:174:in `call!'
omniauth (1.1.0) lib/omniauth/strategy.rb:157:in `call'
omniauth (1.1.0) lib/omniauth/strategy.rb:177:in `call!'
omniauth (1.1.0) lib/omniauth/strategy.rb:157:in `call'
omniauth (1.1.0) lib/omniauth/builder.rb:48:in `call'
sass (3.1.19) lib/sass/plugin/rack.rb:54:in `call'
warden (1.1.1) lib/warden/manager.rb:35:in `block in call'
warden (1.1.1) lib/warden/manager.rb:34:in `catch'
warden (1.1.1) lib/warden/manager.rb:34:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
rack (1.4.1) lib/rack/etag.rb:23:in `call'
rack (1.4.1) lib/rack/conditionalget.rb:25:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/head.rb:14:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/flash.rb:242:in `call'
rack (1.4.1) lib/rack/session/abstract/id.rb:205:in `context'
rack (1.4.1) lib/rack/session/abstract/id.rb:200:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/cookies.rb:338:in `call'
activerecord (3.2.6) lib/active_record/query_cache.rb:64:in `call'
activerecord (3.2.6) lib/active_record/connection_adapters/abstract/connection_pool.rb:473:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
activesupport (3.2.6) lib/active_support/callbacks.rb:405:in `_run__60653626266012267__call__4496837804684830799__callbacks'
activesupport (3.2.6) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.6) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
activesupport (3.2.6) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.6) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/reloader.rb:65:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
railties (3.2.6) lib/rails/rack/logger.rb:26:in `call_app'
railties (3.2.6) lib/rails/rack/logger.rb:16:in `call'
quiet_assets (1.0.1) lib/quiet_assets.rb:20:in `call_with_quiet_assets'
actionpack (3.2.6) lib/action_dispatch/middleware/request_id.rb:22:in `call'
rack (1.4.1) lib/rack/methodoverride.rb:21:in `call'
rack (1.4.1) lib/rack/runtime.rb:17:in `call'
activesupport (3.2.6) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.4.1) lib/rack/lock.rb:15:in `call'
actionpack (3.2.6) lib/action_dispatch/middleware/static.rb:62:in `call'
airbrake (3.1.1) lib/airbrake/rack.rb:30:in `call'
airbrake (3.1.1) lib/airbrake/user_informer.rb:12:in `call'
railties (3.2.6) lib/rails/engine.rb:479:in `call'
railties (3.2.6) lib/rails/application.rb:220:in `call'
rack (1.4.1) lib/rack/content_length.rb:14:in `call'
railties (3.2.6) lib/rails/rack/log_tailer.rb:17:in `call'
thin (1.3.1) lib/thin/connection.rb:80:in `block in pre_process'
thin (1.3.1) lib/thin/connection.rb:78:in `catch'
thin (1.3.1) lib/thin/connection.rb:78:in `pre_process'
thin (1.3.1) lib/thin/connection.rb:53:in `process'
thin (1.3.1) lib/thin/connection.rb:38:in `receive_data'
eventmachine (0.12.10) lib/eventmachine.rb:256:in `run_machine'
eventmachine (0.12.10) lib/eventmachine.rb:256:in `run'
thin (1.3.1) lib/thin/backends/base.rb:61:in `start'
thin (1.3.1) lib/thin/server.rb:159:in `start'
rack (1.4.1) lib/rack/handler/thin.rb:13:in `run'
rack (1.4.1) lib/rack/server.rb:265:in `start'
railties (3.2.6) lib/rails/commands/server.rb:70:in `start'
railties (3.2.6) lib/rails/commands.rb:55:in `block in <top (required)>'
railties (3.2.6) lib/rails/commands.rb:50:in `tap'
railties (3.2.6) lib/rails/commands.rb:50:in `<top (required)>'
script/rails:6:in `require'
script/rails:6:in `<top (required)>'
-e:1:in `load'
-e:1:in `<main>'

如果我继续登录(没有在 Twitter 页面上单击取消),那么一切都会按预期正常运行。 Facebook 也一样,我可以正常登录,但如果我在 Facebook 页面上按“取消”,我会被重定向回来并抛出 500。

有没有办法更好地处理这个问题?我希望能够显示一个漂亮的页面。

【问题讨论】:

  • 如果是 500,请包含堆栈跟踪。如果是 401,那是意料之中的,对吧?
  • 可能你的 twitter 应用 id/secret 有误或者没有发送到 twitter。
  • @Zabba: twitter app id/secret 是正确的,他们可以登录,问题只有在他们取消时才会出现。我会用这个更新问题。
  • @Leopd:我添加了堆栈跟踪。
  • 我在 Rails 3 应用程序上使用 OmniAuth,当我在 Google 页面上点击取消时,它会将我发送到此处:/auth/failure?message=invalid_credentials&strategy=google_oauth2

标签: ruby-on-rails omniauth


【解决方案1】:

当出现故障时,大部分时间取决于故障的类型,OmniAuth 将调用OmniAuth.config.on_failure,默认情况下设置为OmniAuth::FailureEndpoint。默认情况下,它应该在开发模式下引发异常,否则重定向:

def call
  raise_out! if ENV['RACK_ENV'].to_s == 'development'
  redirect_to_failure
end

根据the docs,默认端点是/auth/failure

如果这对您来说没有按预期工作,那么您可以通过将其添加到您的初始化程序来强制重定向始终发生,即使在开发模式下也是如此:

class SafeFailureEndpoint < OmniAuth::FailureEndpoint
  def call
    redirect_to_failure
  end
end

OmniAuth.config.on_failure = SafeFailureEndpoint

来自https://github.com/intridea/omniauth/issues/616的更简洁的解决方案

# Added to config/initializers/omniauth.rb
OmniAuth.config.on_failure = Proc.new { |env|
  OmniAuth::FailureEndpoint.new(env).redirect_to_failure
}

【讨论】:

  • 我将检查该链接并进行更多调查,但我显示的回溯来自生产,而不是开发。
  • 为omniauth 'OmniAuth.config.logger = Rails.logger' 设置日志记录可能会有所帮助
  • 我正在设置记录器,但我不确定这会有什么帮助。我注释掉了 failure_endpoint 中会引发开发异常的行,但我仍然得到与以前相同的异常,所以不是这样。
  • 我的意思是日志可能有助于了解正在发生的事情
  • 我对您的答案进行了很多编辑,以提供一个可行的解决方案(或解决方法)。您最初的答案没有提供解决方案,但它为我指明了正确的方向,我希望您的答案被接受(这样您就可以获得声誉)。可以吗?
【解决方案2】:

我有同样的问题,(facebook取消点击)

添加后

# Added to config/initializers/omniauth.rb
OmniAuth.config.on_failure = Proc.new { |env|
  OmniAuth::FailureEndpoint.new(env).redirect_to_failure
}

实现了认证回调路由

在 config/routes.rb 中

match '/auth/failure' => 'sessions#failure' 

会话控制器看起来像

class SessionsController < ApplicationController
  def failure
    redirect_to #route that you want redirect
  end
end

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,在使用 Pramod 的解决方案时,我遇到了“未知操作”错误,但在我将回调路由更改为

    后工作正常

    config/routes.rb

    devise_scope :user do
      get '/users/auth/failure' => 'sessions#failure'
    end   
    

    Rails 3.2.14
    设计 3.1.1
    Omniauth 1.1.4

    【讨论】:

    • 非常感谢!
    【解决方案4】:

    对于那些使用 omniauth_facebook 和类似 Users::OmniauthCallbacksController 的用户,请使用:

    config/routes.rb

    devise_scope :user do
      get '/omniauth/failure' => 'users/omniauth_callbacks#failure'
    end
    

    app/controllers/users/omniauth_callbacks_controller.rb

    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      def facebook
        ...
      end
      def failure
        redirect_to root_path
      end
    end
    

    如果您使用的是 FB 弹出窗口

    app/controllers/users/omniauth_callbacks_controller.rb

    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      def facebook
        ...
      end
      def failure
        if request.env['HTTP_REFERER'] == "https://www.facebook.com/"
          render 'failure', :layout => false
        else
          redirect_to root_path
        end
      end
    end
    

    app/views/users/omniauth_callbacks/failure.html.haml

    :javascript
      window.close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      • 2022-11-08
      相关资源
      最近更新 更多