ОК. У нас есть приложение, которое отлично работает. Несколько недель go (теперь бывший) сотрудник сделал довольно масштабное изменение, которое, казалось, вызвало довольно специфическую ошибку, и я пытаюсь выяснить, что является реальной проблемой, и, конечно, решить ее.
Короче говоря, вот сценарий, который терпит неудачу:
POST Войти и получить информацию о пользователе
В приложении мы используем devise (я полагаю, 4.6.2) для аутентификации пользователей и CanCanCan для авторизации ресурсов и Ahoy для отслеживания определенных типов пользователей (в данном случае администраторов).
У нас есть два соответствующих маршрута для сбоя, с которым мы сталкиваемся:
/users/sign_in
<- это маршрут разработки </li> GET /user
<- это маршрут, который возвращает некоторую соответствующую информацию о текущем пользователе, включая роль пользователя и <strong>токен JWT , который они могут использовать для выполнять вызовы API
Конечная точка GET /user
определяется внутри контроллера: UsersController < V2::ApplicationController
, контроллер приложения имеет несколько хуков, соответствующий: before_action :authenticate_user!, :update_current_session
, где update_current_session
похоже это:
def current_session
return unless current_user
@current_session ||= current_user.sessions.find_by_session_id(cookies.signed[:_session_id])
end
def update_current_session
return unless current_session
current_session.accessed!(request)
end
Итак, насколько я понимаю, authenticate_user!
использует devise и затем вызывает функцию update_current_session.
Happy Flow - Как все работало раньше:
Мы есть несколько внутренних тестов / скриптов, которым нужен токен, который возвращает /user
, потому что они выполняют вызовы API для нашего приложения. Таким образом, они сделали следующее:
- Выполните вызов POST для
/users/sign_in
с телом, которое выглядит как
{
"user": {
"email": "email@email.com",
"password": "whatever"
}
}
Получить ответ 200 OK с телом
success: "true"
. Устанавливает некоторые файлы cookie (ответ имеет несколько
Set-Cookie
заголовков:
Set-Cookie: ahoy_visit=[REDACTED]; path=/; expires=Mon, 20 Apr 2020 13:34:21 GMT; HttpOnly
Set-Cookie: _session_id=[REDACTED]; path=/; expires=Mon, 20 Apr 2020 10:34:21 GMT; HttpOnly
Set-Cookie: st_session=[REDACTED]; path=/; expires=Wed, 20 May 2020 09:34:21 GMT; HttpOnly
Set-Cookie: _safe_cookies__known_cookies=ahoy_visitor%7Cahoy_visit%7C_session_id%7Cst_session; path=/; expires=Thu, 18 Apr 2030 09:34:21 GMT; HttpOnly
Вызовите GET
/user
с заголовком
Cookie
, который является просто всеми этими параметрами Set-Cook ie вместе (или только несколькими
Cookie
заголовками, оба работают Получите ответ 200 OK с соответствующий орган.
В заключение:
- POST sign_in - получить набор куки
- Позвонить GET / пользователю с куки
- Успех
Сбои после изменения
С тех пор, как бывшие сотрудники меняют соответствующий поток действий, описанный выше, терпит неудачу. Текущая ситуация такова:
- POST sign_in - получить набор файлов cookie
- Позвонить GET / пользователю с файлами cookie
- Получить 401 Несанкционированный
После попытки выяснить, что не так (в основном через Postman и некоторые скрипты), я заметил кое-что довольно странное:
При первом вызове POST /users/sign_in
st_session cook ie кажется * на 1087 * короче , чем было раньше. Если мы дважды вызываем POST /users/sign_in
, то поток работает:
- POST sign_in - получить набор файлов cookie (кажется, что st_session искажен или что-то отсутствует)
- POST sign_in снова - получить набор файлов cookie (теперь st_session выглядит нормально)
- Позвонить GET / пользователю с файлами cookie
- Работает - получает правильный ответ от сервера
Кажется, st_session
из-за конфигурации внутри session_store.rb
:
Rails.application.config.session_store :cookie_store, key: 'st_session', expire_after: (Rails.env.production? ? 1.hour : 1.month), secure: Rails.env.production?
Сводка
До изменения работал следующий поток ОК:
- POST sign_in - получить набор файлов cookie
- Вызов GET / пользователя с печеньем
- Успех
После изменения поток завершается с 401:
- POST sign_in - получить набор печенья
- Позвонить GET / пользователю с файлами cookie
- Получить 401 Несанкционированный
Вызов sign_in дважды подряд работает:
- POST sign_in
- POST sign_in снова
- Позвонить GET / пользователю с cookie
- Работает - получает правильное разрешение Понсе с сервера
Отладка / Выяснение того, что не так
Я смотрел на devise.rb
и на sessions_controller
, но кажется, что сбой 401 происходит за пределами этих мест .
Кто-нибудь знает, что может вызвать эту проблему? Я пытаюсь отладить и найти, в чем проблема, но не могу добиться значительного прогресса. Похоже, что-то связано с Devise / Warden, но я не слишком знаком с тем, что там происходит.
Я бы хотел знать, кто хранит st_session
cook ie и что хранится в нем, потому что кажется, что в первый раз чего-то не хватает (потому что st_session) короче, и похоже, что devise не может правильно аутентифицировать пользователя на основе этого значения.
Any помощь приветствуется, даже направьте меня в соответствующие места в коде, я могу искать ответы / помощь в отладке
Спасибо.