Как обрабатывать ошибки аутентификации при вызовах ajax? - PullRequest
1 голос
/ 20 октября 2019

В моем контроллере rails есть два типа обработчиков: один тип является обычным ответом с веб-страницей, другой предназначен для ответа на запросы $ http на получение от Angular и возвращает json для обработки кодом JavaScript страниц.

Я использую devise, и этот код находится в верхней части моего контроллера приложений.

 protect_from_forgery
 before_action :authenticate_user!
 after_action :set_csrf_cookie

Проблема в том, что когда, например, логин устарел, я думаю, что authenticate_user возвращает мой "неавторизованный" вебстраницу для звонящего, а не json, который сообщал бы звонившему, что текущий пользователь больше не авторизован, и тогда я мог бы правильно обработать условие на стороне клиента.

Любые мысли об эффективном способе сделать это, без необходимости удалять authenticate_user! из контроллера приложений.

Большинство моих контроллеров имеют обработчики для примерно 15 маршрутов, около 50/50, которые предназначены для возврата json к вызовам ajax, а другие возвращают веб-страницы. Мне нравится безопасность, которую authenticate_user! в контроллере приложения предоставляет, и не решается удалить его и вместо этого должен иметь различный код для обеспечения безопасности в каждом из моих методов.

Спасибо.

1 Ответ

1 голос
/ 21 октября 2019

Чтобы понять, как это работает, вам действительно нужно попасть в Warden (в основе которого лежит устройство) и Rack . before_action :authenticate_user! вызывает Warden.authenticate! и просит его идентифицировать пользователя. Надзиратель идентифицирует пользователей с помощью стратегий. Стратегия может быть просто с помощью session[:user_id] найти пользователя из базы данных (что происходит в 99% случаев в Devise) или что-то более новое, например, HTTP Basic Auth.

Если все доступные стратегии дают сбой,приложение сбоя называется. Это приложение Rack. В Devise это просто базовый контроллер Rails (контроллеры Rails являются Rack-совместимыми приложениями), который обычно возвращает перенаправление. Если вы работаете с Rails в среде разработки, вы можете получить ответ HTML, хотя в качестве обработчика ошибок, который показывает вам эти дружественные маленькие страницы исключений, вы можете приступить.

Вы можете настроить ответ, предоставив свое собственное приложение для сбоя:

class CustomAuthFailure < Devise::FailureApp
  def respond
    self.status = 401 
    self.content_type = 'json'
    self.response_body = {"errors" => ["Invalid login credentials"]}.to_json
  end 
end
# config/initializers/devise.rb
config.warden do |manager|
  manager.failure_app = CustomAuthFailure
end 
...