API Auth - rubyhat/fastyshop-backend GitHub Wiki

🔐 Авторизация (Auth API)

Контроллер: Api::V1::AuthController
Версия: v1
Слой: Публичный API, доступен без аутентификации для login и refresh


Пресет пользователей

  1. 77000000001 - супер админ
  2. 77000000002 - супер менеджер
  3. 77000000003 - продавец
  4. 77000000004 - обычный юзер

Пароль у всех - UserPassword1@


📘 Общая логика

API отвечает за работу с JWT токенами:

  • Генерация токенов на основе номера телефона и пароля
  • Обновление access_token по refresh_token
  • Выход пользователя (удаление refresh_token из Redis)

Все access_token токены проверяются и валидируются при помощи JwtService, а refresh_token хранятся и проверяются через TokenStorageRedis.


🔓 POST /api/v1/auth/login

Авторизация пользователя по номеру телефона и паролю. Возвращает пару JWT-токенов (access и refresh) при успешном входе.

🔹 Входные параметры:

Поле Тип Обязательный Пример
phone string +77001234567
password string Secret123!

✅ Ответ (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI..."
}

❌ Ошибка (401 Unauthorized):

{
  "error": {
    "key": "auth.invalid_credentials",
    "message": "Неверный логин или пароль",
    "code": 401,
    "status": "unauthorized"
  }
}

✅ Чек-лист по методу

Пункт Значение
🔒 Требуется ли access token
🔐 Политики доступа (Pundit) Не применяются
🔗 Зависимости (модели/условия) User должен быть активным (is_active: true)

📋 Валидации запроса

  1. phone — обязательное поле
  2. password — обязательное поле
  3. Проверка соответствия учетным данным пользователя
  4. Пользователь не должен быть деактивирован

💼 Бизнес-логика

  • Поиск пользователя по номеру телефона.
  • Проверка пароля через bcrypt.
  • Проверка, что пользователь активен.
  • Генерация access_token и refresh_token.
  • Сохранение refresh_token в Redis.
  • Ответ с токенами для клиента.

📚 Кейсы использования

🧑‍💻 Кейс 1: Покупатель входит в личный кабинет

Пользователь заходит на страницу входа, вводит номер телефона и пароль. После успешного входа получает токены и может просматривать историю заказов.

🛍️ Кейс 2: Продавец авторизуется, чтобы создать магазин

Продавец ранее зарегистрировался. Теперь он входит через /auth/login, получает токены и может создать SellerProfile.

🚫 Кейс 3: Пользователь вводит неверный пароль

При попытке входа с неправильным паролем сервер возвращает 401 Unauthorized с сообщением "Неверный номер телефона или пароль".


📎 Swagger - Будет позже


🔁 POST /api/v1/auth/refresh

Обновление access-токена с помощью действующего refresh-токена. Используется, когда access-токен истёк или скоро истекает.

🔹 Входные параметры:

Поле Тип Обязательный Пример
refresh_token string eyJhbGciOiJIUzI1NiIsInR5cCI...

✅ Ответ (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
  "refresh_token": "b7335d2a-789e-4416-b542-ff45087..."
}

❌ Ошибки:

  • 401 если токен невалиден или просрочен
  • 403 если токен не найден в Redis

✅ Чек-лист по методу

Пункт Значение
🔒 Требуется ли access token ❌ Нет
🔐 Политики доступа (Pundit) Не применяются
🔗 Зависимости (модели/условия) Токен должен быть найден в Redis и быть активным

📋 Валидации запроса

  1. refresh_token — обязательный параметр (в теле как x-www-form-urlencoded)
  2. Проверка существования токена в Redis
  3. Проверка срока действия токена
  4. Проверка активности пользователя

💼 Бизнес-логика

  • Поиск refresh-токена в Redis.
  • Проверка его валидности и срока действия.
  • Поиск пользователя, которому принадлежит токен.
  • Генерация нового access- и refresh-токена.
  • Старый refresh-токен инвалидируется.
  • Новый refresh-токен сохраняется в Redis.
  • Ответ клиенту с новой парой токенов.

📚 Кейсы использования

🔄 Кейс 1: Фронтенд получил 401 и автоматически обновляет access-токен

У клиента истёк access-токен. Он отправляет POST /auth/refresh с действующим refresh-токеном, получает новую пару токенов и повторяет оригинальный запрос.

🔐 Кейс 2: Пользователь не заходил в систему несколько дней

Сессия клиента истекла, но refresh-токен ещё действителен. Пользователь возвращается, получает новую пару токенов без необходимости логина.

🧨 Кейс 3: Пользователь был деактивирован админом

Даже при наличии действующего refresh-токена, сервер отклонит запрос, если пользователь деактивирован (is_active: false).


📎 Swagger - Будет позже


🚪 POST /api/v1/auth/logout

Выход пользователя из системы. Refresh-токен пользователя удаляется из Redis, что делает невозможным его дальнейшее использование для обновления access-токена.

🔹 Заголовки:

POST /auth/logout
Authorization: Bearer <access_token>

✅ Ответ:

  • 200 OK (пустой)

📎 Swagger - Будет позже


❌ Пример ошибки (отсутствие access токена — 401 Unauthorized)

{
  "error": {
    "key": "auth.unauthorized",
    "message": "Неавторизовано",
    "code": 401,
    "status": "unauthorized"
  }
}

🧩 Связанные сущности

Сущность Назначение
User Аутентифицируемая модель
JwtService Генерация и валидация access / refresh JWT
TokenStorageRedis Redis-хранилище refresh токенов

✅ Чек-лист по методу

Пункт Значение
🔒 Требуется ли access token
🔐 Политики доступа (Pundit) Нет — используется authenticate_user!
🔗 Зависимости (модели/условия) Пользователь должен быть авторизован

📋 Валидации запроса

  1. Проверка наличия access-токена
  2. Декодирование access-токена и идентификация пользователя
  3. Удаление связанного refresh-токена из Redis

💼 Бизнес-логика

  • Проверка access-токена из заголовка Authorization.
  • Поиск и идентификация пользователя по access-токену.
  • Удаление refresh-токена пользователя из Redis (в т.ч. всех сессий, если реализовано).
  • Возврат пустого ответа 204 No Content.

📚 Кейсы использования

🔓 Кейс 1: Пользователь вручную выходит из аккаунта

Пользователь нажимает кнопку “Выход” в личном кабинете. Фронтенд отправляет POST /auth/logout, сервер удаляет refresh-токен, и пользователь больше не может обновить access-токен без повторного входа.

🧪 Кейс 2: Автотест проверяет завершение сессии

После логина и выполнения действий, автотест вызывает POST /auth/logout, проверяет что access/refresh-токены стали невалидны, и начинает новую сессию.

🔐 Кейс 3: Пользователь вышел на одном устройстве, но остался на другом

В текущей реализации удаляется конкретный refresh-токен, поэтому при мультисессионности (если будет реализована) другие устройства остаются в системе.


📎 Swagger - Будет позже


📄 TODO / Идеи

  • Ограничить число попыток входа (rate limit)
  • Логировать дату и IP входа
  • Возможность "выйти со всех устройств"