Files
docs/apps/backend-scenarios/login-jwt.md
T

86 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Логин по email и выдача JWT (Backend)
---
# Сценарий 1.1: Логин и JWT
## Бизнес-цель
Пользователь сайта или приложения входит по **email и паролю**. Система проверяет учётные данные, обновляет отметку последнего входа и выдаёт **JWT**, чтобы дальнейшие запросы к API выполнялись от имени этого пользователя без хранения сессии на сервере (stateless API).
## Точки входа
| Тип | Метод + URL | Класс |
| --- | --- | --- |
| HTTP | `POST /user/login` | `App\Controller\UserController::login` |
| HTTP | `GET /user/logout` | `App\Controller\UserController::logout` (ответ-заглушка; инвалидация токена на сервере не показана в коде) |
| HTTP | `GET /user/` | `App\Controller\UserController::index` — текущий пользователь по JWT (`#[IsGranted('ROLE_USER')]`) |
Асинхронные сообщения и CLI для этого сценария **не используются**.
## Пошаговый алгоритм (flow)
1. Клиент отправляет JSON с полями `username` (фактически email) и `password` (см. OpenAPI в контроллере).
2. `UserController::login` вручную парсит тело; при отсутствии полей отвечает `400` с текстом `Missing credentials`.
3. Значения кладутся в `App\Dto\UserLoginDto`; срабатывает Symfony Validator по атрибутам DTO.
4. Вызывается `App\Service\User\AuthenticationService::jsonAuth($dto)`:
- в `App\Repository\UserRepository` выполняется поиск `User` по **`email = md5(введённый email)`** (в БД в колонке `users.email` хранится **хэш**, а не открытый email);
- пароль проверяется через `UserPasswordHasherInterface::isPasswordValid`.
5. При неверной паре или отсутствии пользователя контроллер возвращает `400` с сообщением о неверных учётных данных.
6. При успехе вызывается `$user->updateLoggedIn()`, `EntityManager::flush()` — в БД обновляется поле `loggedIn`.
7. Lexik JWT: `JWTTokenManagerInterface::create($user)` формирует токен; в ответ уходит JSON: `successful`, `token`, `user` (массив из `User::toArray()``uid`, `bdate`, `roles`, `regionId`, `loggedIn`).
## Mermaid
```mermaid
sequenceDiagram
participant C as Клиент
participant UC as UserController
participant V as Validator
participant AS as AuthenticationService
participant UR as UserRepository
participant EM as EntityManager
participant JWT as JWTTokenManagerInterface
C->>UC: POST /user/login {username, password}
UC->>V: validate(UserLoginDto)
V-->>UC: ок / ошибки
UC->>AS: jsonAuth(dto)
AS->>UR: findOneBy email = md5(dto.email)
UR-->>AS: User | null
AS-->>UC: {user, isPasswordValid}
alt неверный пароль или нет пользователя
UC-->>C: 400
else успех
UC->>EM: flush (updateLoggedIn)
UC->>JWT: create(User)
UC-->>C: 200 {token, user}
end
```
## Внешние зависимости
| Система | Участие |
| --- | --- |
| PostgreSQL | таблица `users` (`App\Entity\User`) |
| Lexik JWT | генерация и последующая валидация токена |
| Bitrix / Инфоклиника / Redis / SMS | **не задействованы** в этом сценарии |
## Обработка ошибок и edge cases
- **Нет полей credentials** — `400`, `Missing credentials`.
- **Ошибки валидации DTO** — `400`, `successful: false`, `errors` (строка нарушений).
- **Неверный email/пароль** — единый ответ `400` с текстом «Не правильное имя пользователя или пароль».
- **Согласованность с JWT**: `App\Service\DecoderJWT\JWTDecoderService::getUser()` восстанавливает пользователя по `username` из payload и полю `email` в БД — это тот же «логин», что хранится в `User` после регистрационных сценариев (часто `md5(...)`).
## Ссылки на классы
- `apps/backend/src/Controller/UserController.php`
- `apps/backend/src/Service/User/AuthenticationService.php`
- `apps/backend/src/Dto/UserLoginDto.php`
- `apps/backend/src/Entity/User.php`
- `apps/backend/src/Repository/UserRepository.php`
- Конфигурация security/JWT: `apps/backend/config/packages/security.yaml`, `lexik_jwt_authentication.yaml`
См. также [backend-ddd.md](../backend-ddd.md).