Подтвердить что ты не робот

Как спасти OmniAuth:: Стратегии:: OAuth2:: CallbackError?

Я создаю приложение Rails с Omniauth для входа в систему. Для аутентификации Google я использую Стратегия OmniAuth Google OAuth2.

Когда пользователь нажимает кнопку "разрешить доступ", все работает отлично. Но когда пользователь нажимает кнопку "нет благодарности", появляется ошибка ниже.

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

Но не повезло.

Любая идея?

Спасибо:)

4b9b3361

Ответ 1

Это происходит потому, что аутентификация происходит в промежуточном программном обеспечении, поэтому ваш контроллер не участвует в нем. Это где возникает исключение, а вызываемый код this

Я думаю, что вы можете справиться с такой ошибкой, указав обратный вызов в инициализаторе 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 с сообщением об ошибке, поэтому вы должны определить маршрут для этого пути и обработать его в своем приложении. Имейте в виду, что это не произойдет в режиме разработки, поэтому вам нужно попробовать его в других envs. Если этого не происходит в производстве, попробуйте обновить свой камень omniauth до версии 1.1.0

Ответ 2

Вы можете установить процесс on_failure в инициализаторе omniauth еще более чистым способом:

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

Ответ 3

Я решил эту проблему с первым предложением Фабио.

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

В моем UserController

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

Ответ 4

Там используется конфигурация, использующая /auth/failure вместо повышения ошибки.

Я использую OmniAuth 1.2.2, и когда я проверяю FailureEndpoint, я нашел код как this:

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