Разработка: как вернуть 401 несанкционированный без перенаправления, если пользователь не авторизован

#ruby-on-rails #ruby #devise

#ruby-on-rails #ruby #разработка

Вопрос:

Версия Rails: 4.0.13

Версия разработки: 3.2.0

Когда пользователь пытается просмотреть страницу, на просмотр которой у него нет прав, мое приложение перенаправляет их на страницу входа.

Если пользователь не вошел в систему, я хочу:

  1. Не перенаправляет пользователя на новый URL и
  2. Верните ответ «401 неавторизованный» с пустым телом

До сих пор я пытался переопределить authenticate_user! вот так:

 class BaseApiController < ActionController::Base
  before_filter :authenticate_user!

  def authenticate_user!
    head :unauthorized
  end
end
  

Однако, хотя это возвращает ‘401 неавторизованный’, оно также сначала перенаправляет на URL входа.

Ответ №1:

Основываясь на ответе @vinyl, следующий вернет 401 без перенаправления, если пользователь не вошел в систему:

 # lib/custom_failure.rb
class CustomFailure < Devise::FailureApp
  def respond
    http_auth
  end
end

# config/initializers/devise.rb
config.warden do |manager|
  manager.failure_app = CustomFailure
end
  

Вы можете настроить respond перенаправление в некоторых случаях и выдачу 401 случаев в других. Для моего варианта использования было достаточно следующего:

 class CustomFailure < Devise::FailureApp
  def respond
    if request.env['REQUEST_PATH'].start_with?('/api')
      http_auth
    else
      redirect
    end
  end
end
  

Я не понимаю, почему переопределение authenticate_user! здесь не сработало.

Комментарии:

1. Rails 5.2 и 6.0 не используют request.env['REQUEST_PATH'] . И в любом случае, лучше использовать общедоступные методы, предусмотренные для ActionDispatch::Request , когда они доступны. Попробуйте использовать request.original_fullpath.start_with?('/api') .

Ответ №2:

Это то, что вы ищете?

https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-when-the-user-can-not-be-authenticated

Это все равно перенаправляет пользователя, хотя вы можете контролировать, куда направляется это перенаправление.

Комментарии:

1. Похоже, что это в правильном направлении, но для меня этого недостаточно, чтобы решить мою проблему. Однако я изучаю это более внимательно.

2. Мне любопытно, что вы ожидаете увидеть от пользователя, когда он пытается получить доступ к URL, защищенному аутентификацией, если перенаправления нет. Вы работаете только с кодовой базой API?

3. Нет, некоторые маршруты являются маршрутами API (начинаются с /api/v1/ ), а другие маршруты являются обычным приложением Rails. Если пользователь не вошел в систему и пытается получить доступ к маршруту API, я хочу, чтобы он видел 401 и никуда не перенаправлялся.