42

我正在使用Omniauth构建 Rails 应用程序以进行登录服务。要对 Google 进行身份验证,我正在使用OmniAuth Google OAuth2 Strategy

当用户单击“允许访问”按钮时,一切正常。但是当用户单击“不,谢谢”按钮时,会引发以下错误。

OmniAuth::Strategies::OAuth2::CallbackError

我尝试在应用程序控制器中添加以下救援代码。

class ApplicationController < ActionController::Base
  rescue_from OmniAuth::Strategies::OAuth2::CallbackError, :with =>
    :omniauth_callback_error_handler

 protected

 def omniauth_callback_error_handler
  redirect_to init_sign_in_users_path
 end
end

但没有运气。任何的想法?

4

4 回答 4

66

您可以在omniauth 初始化程序中以更简洁的方式设置on_failure proc:

OmniAuth.config.on_failure = UsersController.action(:oauth_failure)
于 2012-06-29T05:35:37.760 回答
39

发生这种情况是因为身份验证发生在中间件中,因此您的控制器不参与其中。这是引发异常的地方,被调用的代码是这个

我认为您可以通过使用此类代码在 OmniAuth 初始化程序中定义回调来处理此类错误

OmniAuth.config do |config|
  config.on_failure do
    # your handling code invoked in the context of a rack app
  end
end

否则三个月前的提交会引入这种行为

def redirect_to_failure
  message_key = env['omniauth.error.type']
  new_path = "#{env['SCRIPT_NAME']}#{OmniAuth.config.path_prefix}/failure?message=#{message_key}"
  Rack::Response.new(["302 Moved"], 302, 'Location' => new_path).finish
end

这表明在错误时您的用户会被重定向到/auth/failure错误消息,因此您应该能够为该路径定义路由并在您的应用程序中处理它。请记住,这不会在开发模式下发生,因此您需要在其他环境中尝试。如果这在生产中没有发生,请尝试将您的 omniauth gem 升级到版本 1.1.0

于 2012-05-24T12:43:59.150 回答
18

我已经用 Fabio 的第一个建议解决了这个问题。

OmniAuth.config.on_failure = Proc.new do |env|
  UsersController.action(:omniauth_failure).call(env)
  #this will invoke the omniauth_failure action in UsersController.
end

在我的用户控制器中

class UsersController < ActionController::Base
  def omniauth_failure
    redirect_to init_sign_in_users_path
    #redirect wherever you want.
  end
end
于 2012-05-24T18:36:07.117 回答
1

有一个配置可以使用/auth/failure,而不是引发错误。

我使用 OmniAuth 1.2.2,当我检查 FailureEndpoint 时,我发现代码是这样

def call
  raise_out! if OmniAuth.config.failure_raise_out_environments.include?(ENV['RACK_ENV'].to_s)
  redirect_to_failure
end

并在此处failure_raise_out_environments定义:

def self.defaults
  @defaults ||= {
    # other configurations
    :failure_raise_out_environments => ['development']
  }
end

可以配置环境,因此解决方案很简单。我使用 Rails,所以我把下面的代码放在一个初始化文件中:

OmniAuth.configure do |config|
  # Always use /auth/failure in any environment
  config.failure_raise_out_environments = []
end
于 2015-06-15T07:43:12.547 回答