Skip to main content

Authentication

В проекте два независимых auth-потока: для пользователей и для артистов. Оба используют одинаковые механизмы.

Механизм

  • JWT в HttpOnly cookies (не в заголовках)
  • Два токена: access_token (5 мин) и refresh_token (30 дней)
  • Сессии хранятся в PostgreSQL (UserSession, ArtistSession)
  • Инвалидация через удаление сессии из БД

Эндпоинты пользователей

МетодМаршрутОписание
POST/api/v1/users/auth/registerРегистрация
POST/api/v1/users/auth/loginВход
POST/api/v1/users/auth/refreshОбновить access token
POST/api/v1/users/auth/logoutВыход (удаляет сессию)
GET/api/v1/users/auth/meТекущий пользователь
POST/api/v1/users/auth/2fa/enableВключить 2FA
POST/api/v1/users/auth/2fa/verifyВерифицировать TOTP
POST/api/v1/users/auth/2fa/disableОтключить 2FA
GET/api/v1/users/auth/oauth/:providerOAuth редирект
GET/api/v1/users/auth/oauth/:provider/callbackOAuth callback
POST/api/v1/users/auth/password/forgotЗапросить сброс пароля
POST/api/v1/users/auth/password/resetСбросить пароль по токену

Эндпоинты артистов

Аналогичны пользовательским, но по пути /api/v1/artists/auth/*.

Регистрация и вход

POST /api/v1/users/auth/register
Content-Type: application/json

{
"username": "johndoe",
"email": "john@example.com",
"password": "SecurePass123"
}

Ответ устанавливает access_token и refresh_token в HttpOnly cookies.

POST /api/v1/users/auth/login
Content-Type: application/json

{
"email": "john@example.com",
"password": "SecurePass123"
}

Refresh

POST /api/v1/users/auth/refresh

Читает refresh_token из cookie, выдаёт новый access_token. Старый refresh-токен инвалидируется (rotation).

Защищённые маршруты

Куки отправляются браузером автоматически. Для API-клиентов (Swagger, мобильное приложение):

GET /api/v1/users/me
Cookie: access_token=eyJhbGciOiJIUzI1NiIs...

OAuth 2.0

Поддерживаемые провайдеры: Google, Facebook.

# 1. Редирект на провайдера
GET /api/v1/users/auth/oauth/google

# 2. Провайдер редиректит обратно
GET /api/v1/users/auth/oauth/google/callback?code=...

# 3. API устанавливает cookies и редиректит на WEB_HOST

Переменные окружения:

OAUTH_GOOGLE_CLIENT_ID=
OAUTH_GOOGLE_CLIENT_SECRET=
OAUTH_FACEBOOK_APP_ID=
OAUTH_FACEBOOK_APP_SECRET=
API_BASE_URL=http://localhost:3000

Двухфакторная аутентификация (2FA)

Реализована через TOTP (RFC 6238) — совместима с Google Authenticator, Authy и др.

Включение:

POST /api/v1/users/auth/2fa/enable

Ответ содержит QR-код (base64 PNG) и otpauth:// URI для ручного ввода.

Верификация:

POST /api/v1/users/auth/2fa/verify
Content-Type: application/json

{ "code": "123456" }

При входе с включённой 2FA сервер возвращает requiresTwoFactor: true — клиент должен запросить TOTP-код и отправить его повторно.

Отключение:

POST /api/v1/users/auth/2fa/disable
Content-Type: application/json

{ "code": "123456" }

Сброс пароля

# 1. Запрос письма
POST /api/v1/users/auth/password/forgot
Content-Type: application/json

{ "email": "john@example.com" }

Если SMTP не настроен, токен логируется в консоль (dev-режим).

# 2. Сброс по токену из письма
POST /api/v1/users/auth/password/reset
Content-Type: application/json

{
"token": "reset-token-from-email",
"password": "NewSecurePass123"
}

Использование в NestJS контроллерах

// Только для пользователей
@UserAuth()
@Get('me')
getMe(@Req() req: UserAuthRequest) {
return req.user // UserEntity
}

// Только для артистов
@ArtistAuth()
@Post('tracks')
uploadTrack(@Req() req: ArtistAuthRequest) {
return req.artist // ArtistEntity
}