переделал токен
All checks were successful
Build and Push Docker Images / build-and-push-backend (push) Successful in 13s
Build and Push Docker Images / build-and-push-frontend (push) Successful in 11s
Build and Push Docker Images / deploy-to-k8s (push) Successful in 3m48s

This commit is contained in:
Zuev
2026-05-27 15:19:18 +03:00
parent 52328ae6c0
commit d4ace6aab2
28 changed files with 1227 additions and 125 deletions

View File

@@ -171,19 +171,24 @@ frontend/
## API-клиент (`api.js`)
Все HTTP-запросы проходят через обёртку `apiFetch()`:
Все HTTP-запросы проходят через обёртку `apiFetch()`. Access JWT читается из `localStorage` перед каждым запросом:
```javascript
export async function apiFetch(endpoint, method = 'GET', body = null) {
export async function apiFetch(endpoint, method = 'GET', body = null, retryOnUnauthorized = true) {
const response = await fetch(endpoint, {
method,
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: body ? JSON.stringify(body) : null
headers: getHeaders(body ? 'application/json' : null),
credentials: 'same-origin',
body: body ? JSON.stringify(body) : undefined
});
if (response.status === 401 && retryOnUnauthorized) {
const refreshed = await refreshAccessToken();
if (refreshed) return apiFetch(endpoint, method, body, false);
clearAuthState();
window.location.href = '/';
}
if (!response.ok) {
throw new Error(data?.message || `Ошибка HTTP: ${response.status}`);
}
@@ -200,7 +205,7 @@ export const api = {
};
```
Токен берётся из `localStorage.getItem('token')`.
При `401` клиент один раз вызывает `POST /api/auth/refresh`, обновляет `localStorage.token` и повторяет исходный запрос. Если refresh неуспешен, auth state очищается и пользователь возвращается на страницу входа.
---
@@ -211,11 +216,12 @@ export const api = {
1. Пользователь вводит логин/пароль
2. `script.js` отправляет `POST /api/auth/login`
3. При успехе сохраняет в `localStorage`:
- `token`UUID-токен
- `token`access JWT
- `role` — роль пользователя
- `departmentId` — кафедра пользователя
- `userId` — ID пользователя для личного расписания преподавателя
4. Перенаправляет на соответствующий интерфейс:
4. Refresh-токен сохраняется браузером как `HttpOnly` cookie и недоступен JavaScript
5. Перенаправляет на соответствующий интерфейс:
- `ADMIN``/admin/`
- `EDUCATION_OFFICE``/admin/#schedule-view`
- `DEPARTMENT``/admin/#department-workspace`
@@ -230,13 +236,13 @@ export const api = {
```javascript
export function isAuthenticatedAsAdmin() {
const role = localStorage.getItem('role');
return token && role === 'ADMIN';
return getToken() && role === 'ADMIN';
}
```
### Выход
Кнопка «Выйти» находится в dropdown-меню «Настройки» в footer боковой панели. Очищает `localStorage` и перенаправляет на `/`.
Кнопка «Выйти» вызывает `POST /api/auth/logout`, затем очищает `localStorage` и перенаправляет на `/`.
---