Регистрация нового временного пользователя.
Request:
POST /api/auth/register
Content-Type: application/json{
"login": "testuser123",
"password": "testpass123"
}Success Response (201 Created):
{
"status": "success",
"message": "account has been created or authenticated",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYWJjMTIzIiwiaXNfdGVtcG9yYXJ5Ijp0cnVlLCJleHAiOjE3MDAwMDAwMDAsImlhdCI6MTY5OTk5NjQwMH0...",
"expires_in": 3600
}Cookies:
Set-Cookie: refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000
Error Responses:
| Status Code | Описание | Пример ответа |
|---|---|---|
400 Bad Request |
Невалидный JSON или не соответствует требованиям к логину/паролю | {"status": "error", "message": "login must be at least 8 characters long"} |
409 Conflict |
Логин уже занят | {"status": "error", "message": "login already exists"} |
500 Internal Server Error |
Внутренняя ошибка сервера | {"status": "error", "message": "internal server error"} |
Примеры ошибок валидации:
"login must be at least 8 characters long"- логин короче 8 символов"login must not exceed 16 characters"- логин длиннее 16 символов"password must be at least 8 characters long"- пароль короче 8 символов"password must not exceed 16 characters"- пароль длиннее 16 символов"login cannot be empty"- логин пустой"password cannot be empty"- пароль пустой
Авторизация существующего пользователя.
Request:
POST /api/auth/login
Content-Type: application/json{
"login": "testuser123",
"password": "testpass123"
}Success Response (200 OK):
{
"status": "success",
"message": "account has been created or authenticated",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYWJjMTIzIiwiaXNfdGVtcG9yYXJ5Ijp0cnVlLCJleHAiOjE3MDAwMDAwMDAsImlhdCI6MTY5OTk5NjQwMH0...",
"expires_in": 3600
}Cookies:
Set-Cookie: refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000
Error Responses:
| Status Code | Описание | Пример ответа |
|---|---|---|
400 Bad Request |
Невалидный JSON или не соответствует требованиям | {"status": "error", "message": "login must be at least 8 characters long"} |
401 Unauthorized |
Неверный логин или пароль | {"status": "error", "message": "invalid credentials"} |
500 Internal Server Error |
Внутренняя ошибка сервера | {"status": "error", "message": "internal server error"} |
Примечание: По соображениям безопасности, при неверном логине или пароле возвращается общее сообщение "invalid credentials" без уточнения, что именно неверно.
Обновление access токена с помощью refresh токена.
Request:
POST /api/auth/refresh
Cookie: refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Требования:
- Refresh token должен быть в HTTPOnly cookie (автоматически отправляется браузером)
- Access token НЕ требуется для этого запроса
Success Response (200 OK):
{
"status": "success",
"message": "access token refreshed",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYWJjMTIzIiwiaXNfdGVtcG9yYXJ5Ijp0cnVlLCJleHAiOjE3MDAwMDAwMDAsImlhdCI6MTY5OTk5NjQwMH0...",
"expires_in": 3600
}Примечание: Refresh token остается прежним и не обновляется. Cookie не изменяется.
Error Responses:
| Status Code | Описание | Пример ответа |
|---|---|---|
401 Unauthorized |
Refresh token отсутствует | {"status": "error", "message": "refresh token not found"} |
401 Unauthorized |
Невалидный или истекший refresh token | {"status": "error", "message": "invalid refresh token"} |
401 Unauthorized |
Сессия отозвана | {"status": "error", "message": "session has been revoked"} |
401 Unauthorized |
Сессия истекла | {"status": "error", "message": "session has expired"} |
500 Internal Server Error |
Внутренняя ошибка сервера | {"status": "error", "message": "internal server error"} |
Health check endpoint для мониторинга состояния сервиса.
Request:
GET /healthSuccess Response (200 OK):
OK
Примечание: Возвращает plain text, не JSON.
- Логин: от 8 до 16 символов (любые UTF-8 символы)
- Пароль: от 8 до 16 символов (любые UTF-8 символы)
Примечания:
- Пароли хешируются с использованием Argon2id перед сохранением в БД
- Рекомендуется использовать сложные пароли, но валидация на сложность не применяется
- Логин чувствителен к регистру
Формат: JWT (JSON Web Token)
Алгоритм подписи: HS256 (HMAC-SHA256)
Срок действия: 1 час (по умолчанию, настраивается через JWT_ACCESS_DURATION)
Payload содержит:
{
"user_id": "uuid-пользователя",
"is_temporary": true,
"exp": 1700000000,
"iat": 1699996400
}| Поле | Тип | Описание |
|---|---|---|
user_id |
string | UUID пользователя |
is_temporary |
boolean | Флаг временного пользователя (всегда true для текущей реализации) |
exp |
number | Unix timestamp истечения токена |
iat |
number | Unix timestamp создания токена |
Использование:
Отправляется в заголовке Authorization для защищенных эндпоинтов:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Формат: JWT (JSON Web Token)
Алгоритм подписи: HS256 (HMAC-SHA256)
Срок действия: 30 дней (по умолчанию, настраивается через JWT_REFRESH_DURATION)
Payload содержит:
{
"user_id": "uuid-пользователя",
"is_temporary": false,
"exp": 1702588400,
"iat": 1699996400
}| Поле | Тип | Описание |
|---|---|---|
user_id |
string | UUID пользователя |
is_temporary |
boolean | Всегда false для refresh токенов |
exp |
number | Unix timestamp истечения токена |
iat |
number | Unix timestamp создания токена |
Хранение:
Refresh token сохраняется в HTTPOnly cookie для защиты от XSS атак.
Cookie атрибуты:
HttpOnly- токен недоступен для JavaScriptSecure- передается только по HTTPS (в production)SameSite=Strict- защита от CSRF атакPath=/- доступен для всех путейMax-Age=2592000- время жизни 30 дней
Примечание: Refresh token в БД хранится в виде SHA-256 хеша. Даже при компрометации БД, токены нельзя использовать.
-
Хеширование паролей: Argon2id с параметрами:
- Memory: 64 MB
- Time: 1 iteration
- Threads: 4
- Key length: 32 bytes
-
Хеширование refresh токенов: SHA-256 перед сохранением в БД
-
HTTPOnly cookies: Защита refresh токенов от XSS
-
SameSite cookies: Защита от CSRF атак
-
Валидация входных данных: Проверка длины логина и пароля
-
Prepared statements: Защита от SQL injection
-
Автоматическая очистка: Истекшие сессии удаляются каждый час
- Храните access token в памяти приложения (не в localStorage)
- При получении 401 на защищенных эндпоинтах, вызывайте
/api/auth/refresh - После успешного refresh, повторите исходный запрос с новым access token
- При ошибке refresh (401) перенаправляйте пользователя на login/register
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{"login": "testuser123", "password": "testpass123"}' \
-c cookies.txt -vcurl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"login": "testuser123", "password": "testpass123"}' \
-c cookies.txt -vcurl -X POST http://localhost:8080/api/auth/refresh \
-b cookies.txt -vcurl http://localhost:8080/health