How to rescue OmniAuth::Strategies::OAuth2::CallbackError?

夙愿已清 提交于 2019-12-02 15:29:43

This happens because the authentication happens in a middleware so your controller is not involved in it. This is where the exception is raised and the called code is this

I think you can handle this kind of error by defining a callback in Omniauth initializer with this kind of code

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

Otherwise there is a commit of three months ago which introduce this behavior

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

which states that on errors your user is redirected to /auth/failure with an error message, so you should be able to define a route for that path and handle it in your app. Keep in mind that this won't happen in development mode so you need to try it in other envs. If this doesn't happen in production try to upgrade your omniauth gem to version 1.1.0

Peter P.

You can set the on_failure proc in the omniauth initializer in an even cleaner fashion:

OmniAuth.config.on_failure = UsersController.action(:oauth_failure)
Soundar Rathinasamy

I have solved this problem with the Fabio's first suggestion.

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

In my UsersController

class UsersController < ActionController::Base
  def omniauth_failure
    redirect_to init_sign_in_users_path
    #redirect wherever you want.
  end
end

There's a configuration to use /auth/failure instead of raising an error.

I use OmniAuth 1.2.2 and when I checking the FailureEndpoint I found the code is like this:

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

And the failure_raise_out_environments is defined here:

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

The environment can be configured so the solution is easy. I use Rails so I put below code in an initializer file:

OmniAuth.configure do |config|
  # Always use /auth/failure in any environment
  config.failure_raise_out_environments = []
end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!