переделал токен
This commit is contained in:
@@ -131,16 +131,15 @@ sequenceDiagram
|
||||
|
||||
## Аутентификация
|
||||
|
||||
Система использует простую модель аутентификации без JWT и без полноценного Spring Security:
|
||||
Система использует access JWT и отзывные refresh-токены без включения полноценного Spring Security flow:
|
||||
|
||||
1. Клиент отправляет `POST /api/auth/login` с `username` и `password`
|
||||
2. Backend проверяет пароль через `BCryptPasswordEncoder`
|
||||
3. При успехе возвращается:
|
||||
- UUID-токен (для заголовка `Authorization: Bearer`)
|
||||
- Роль пользователя (`ADMIN`, `EDUCATION_OFFICE`, `DEPARTMENT`, `SCHEDULE_VIEWER`, `TEACHER`, `STUDENT`)
|
||||
- Redirect URL (`/admin/`, `/admin/#schedule-view`, `/admin/#department-workspace`, `/teacher/`, `/student/`)
|
||||
4. Токен хранится в `localStorage` на клиенте
|
||||
1. Клиент отправляет `POST /api/auth/login` с `username` и `password`.
|
||||
2. Backend проверяет пароль через `BCryptPasswordEncoder`.
|
||||
3. При успехе возвращается access JWT для заголовка `Authorization: Bearer <token>` и устанавливается `HttpOnly` refresh-cookie.
|
||||
4. Access JWT хранится в `localStorage`; refresh-токен хранится только в cookie, а в БД сохраняется SHA-256 хэш.
|
||||
5. При истечении access JWT клиент вызывает `POST /api/auth/refresh`; refresh-токен ротируется, старый хэш отзывается.
|
||||
6. `POST /api/auth/logout` отзывает текущий refresh-токен и очищает cookie.
|
||||
|
||||
Токены хранятся в `AuthSessionService` в памяти процесса backend. `AuthorizationInterceptor` проверяет bearer-токен для `/api/**`, кроме `POST /api/auth/login`, и применяет аннотацию `@RequireRoles` на контроллерах и методах. Это означает, что UI-роль в `localStorage` больше не является единственной защитой: backend возвращает `401`, если токена нет, и `403`, если роли недостаточно.
|
||||
Access JWT содержит claim'ы `tenant`, `userId`, `username`, `role`, `departmentId`, `iat`, `exp`, `jti`. `AuthorizationInterceptor` проверяет подпись, срок действия и совпадение `tenant` с `TenantContext`, затем применяет `@RequireRoles`. Это означает, что UI-роль в `localStorage` остаётся только удобством: backend возвращает `401`, если токен отсутствует/некорректен, и `403`, если роли недостаточно.
|
||||
|
||||
`TenantInterceptor` по-прежнему отвечает за выбор БД тенанта по домену. Проверка авторизации выполняется отдельным интерцептором после tenant-resolution.
|
||||
`TenantInterceptor` по-прежнему отвечает за выбор БД тенанта по домену. Проверка авторизации выполняется отдельным интерцептором после tenant-resolution, поэтому токен, выданный на одном домене, не принимается на другом tenant-домене.
|
||||
|
||||
Reference in New Issue
Block a user