Перейти к основному содержимому

1. Auth

Раздел описывает аутентификацию, авторизацию и модель доступа в Smart Parking API.

1.1 Общие правила

Авторизация запросов

Для защищённых эндпоинтов необходимо передавать токен доступа в заголовке:

Authorization: Bearer <access_token>

В MVP используется только access_token.
refresh_token не используется.

Доступ к карте

В MVP подписки не используются.
Все авторизованные пользователи имеют доступ к базовому клиентскому функционалу, включая просмотр карты.

Общие ошибки авторизации

КодТипОписание
400Bad RequestНевалидное тело запроса или отсутствуют обязательные поля.
401UnauthorizedТокен отсутствует, невалиден, истёк или сессия завершена.
403ForbiddenТокен валиден, но у субъекта недостаточно прав для выполнения действия.
409ConflictКонфликт данных, например email уже используется.
422Unprocessable EntityОшибка валидации.
429Too Many RequestsСлишком много попыток входа.

Пример ответа:

{
"error_description": "Missing or invalid access token"
}

1.2 Модель доступа

Доступ к API определяется через:

  • глобальные роли пользователя;
  • членство в партнёрских организациях;
  • разрешения (permissions);
  • область доступа к данным (scope).

Глобальные роли

  • user — обычный пользователь;
  • admin — администратор платформы.

Роли в партнёрской организации

  • partner_owner
  • partner_admin
  • partner_manager
  • partner_analyst
  • partner_viewer

Разрешения (permissions)

Базовый клиентский доступ

  • users.me.view
  • users.me.update
  • users.password.update
  • map.view
  • zones.view
  • occupancy.view
  • forecasts.view
  • routing.create
  • feedback.create

Источники данных

  • sources.create
  • sources.view
  • sources.update
  • sources.delete

Камеры

  • cameras.create
  • cameras.view
  • cameras.update
  • cameras.delete

Парковочные зоны

  • zones.create
  • zones.update
  • zones.delete

Статистика и аналитика

  • analytics.view
  • partner_statistics.view

Управление пользователями партнёра

  • partner_members.view
  • partner_members.invite
  • partner_members.update
  • partner_members.disable
  • partner_access.manage

Административные права платформы

  • admin.users.view
  • admin.users.manage
  • admin.partners.view
  • admin.partners.manage
  • admin.system.view
  • admin.system.manage
  • admin.monitoring.view
  • admin.analytics.view

Область доступа к данным (scope)

Для операций чтения, изменения и удаления используется область доступа:

  • none — доступ отсутствует;
  • own — только объекты, созданные пользователем;
  • assigned — только объекты, явно назначенные пользователю;
  • own_or_assigned — собственные и назначенные объекты;
  • partner_all — все объекты партнёрской организации;
  • global_all — все объекты системы.

Правило проверки доступа

Для защищённого эндпоинта сервер проверяет:

  1. валидность токена;
  2. наличие требуемого разрешения;
  3. принадлежность ресурса нужной области доступа.

1.3 Модель PartnerMembership

Используется в ответах Auth API для описания прав пользователя внутри партнёрской организации.

  • partner_id (integer) — идентификатор партнёрской организации.
  • role (string) — роль пользователя в организации.
  • permissions (string[]) — список разрешений в рамках этой организации.
  • read_scope (string) — область доступа на чтение.
  • write_scope (string) — область доступа на изменение.
  • delete_scope (string) — область доступа на удаление.

Пример:

{
"partner_id": 10,
"role": "partner_manager",
"permissions": [
"sources.create",
"sources.view",
"sources.update",
"cameras.create",
"cameras.view",
"cameras.update",
"zones.create",
"zones.view",
"zones.update"
],
"read_scope": "own_or_assigned",
"write_scope": "own_or_assigned",
"delete_scope": "own"
}

1.4 POST /auth/register

Регистрирует нового обычного пользователя и создаёт новую сессию.

Эндпоинт предназначен для публичной формы регистрации на сайте или в приложении.

Request body (required)

  • email (string) — email пользователя.
  • password (string) — пароль пользователя.
  • full_name (string, optional) — имя пользователя.
  • phone (string, optional) — номер телефона пользователя.

Пользователь, зарегистрированный через этот эндпоинт, создаётся с глобальной ролью user.

Пример запроса

POST /api/v1/auth/register HTTP/1.1
Host: api.parktrack.live
Content-Type: application/json

{
"email": "user@example.com",
"password": "secret_123",
"full_name": "Иван Петров"
}

Response (201)

  • access_token (string) — токен доступа.
  • token_type (string) — всегда Bearer.
  • expires_in (integer) — срок жизни токена в секундах.
  • user (object) — краткая информация о пользователе:
    • user_id (integer)
    • email (string)
    • full_name (string | null)
    • global_roles (string[])

Пример ответа (201)

{
"access_token": "<token>",
"token_type": "Bearer",
"expires_in": 86400,
"user": {
"user_id": 123,
"email": "user@example.com",
"full_name": "Иван Петров",
"global_roles": ["user"]
}
}

Ошибки

КодТипОписание
400Bad RequestНевалидное тело запроса.
409ConflictПользователь с таким email уже существует.
422Unprocessable EntityОшибка валидации полей регистрации.
429Too Many RequestsСлишком много попыток регистрации.

Пример ответа (409)

{
"error_description": "User with this email already exists"
}

1.5 POST /auth/login

Аутентифицирует пользователя и создаёт новую сессию.

Request body (required)

  • login (string) — логин пользователя.
  • password (string) — пароль пользователя.

Пример запроса

POST /api/v1/auth/login HTTP/1.1
Host: api.parktrack.live
Content-Type: application/json

{
"login": "user@example.com",
"password": "secret"
}

Response (200)

  • access_token (string) — токен доступа.
  • token_type (string) — всегда Bearer.
  • expires_in (integer) — срок жизни токена в секундах.
  • user (object) — краткая информация о пользователе:
    • user_id (integer)
    • email (string)
    • full_name (string | null)
    • global_roles (string[])

Пример ответа (200)

{
"access_token": "<token>",
"token_type": "Bearer",
"expires_in": 86400,
"user": {
"user_id": 123,
"email": "user@example.com",
"full_name": "Иван Петров",
"global_roles": ["user"]
}
}

Ошибки

КодТипОписание
400Bad RequestНевалидное тело запроса.
401UnauthorizedНеверный логин или пароль.
429Too Many RequestsСлишком много попыток входа.

Пример ответа (401)

{
"error_description": "Invalid login or password"
}

1.6 POST /auth/password-reset/request

Создаёт запрос на восстановление пароля.

Эндпоинт используется, когда пользователь не может войти в аккаунт и нажимает «Забыли пароль?».

Эндпоинт публичный и не требует авторизации.

Если пользователь с указанным email существует и активен, сервер создаёт одноразовый reset-token, сохраняет его хеш в базе и отправляет письмо со ссылкой для сброса пароля.

Если пользователя с таким email нет или аккаунт неактивен, сервер всё равно возвращает успешный ответ. Это нужно, чтобы нельзя было проверить, зарегистрирован ли email в системе.

Request body (required)

  • email (string) — email пользователя.

Пример запроса

POST /api/v1/auth/password-reset/request HTTP/1.1
Host: api.parktrack.live
Content-Type: application/json

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

Response (200)

  • ok (boolean) — всегда true, если запрос обработан.
  • reset_token (string | null) — reset-token. В production обычно null; может возвращаться в dev-режиме, если SMTP не настроен или явно включён возврат токена.

Пример ответа в production

{
"ok": true,
"reset_token": null
}

Пример ответа в dev-режиме

{
"ok": true,
"reset_token": "Q9a2QY7V2uF9yJj..."
}

Поведение

  • reset-token создаётся только для существующего активного пользователя;
  • в базе хранится не сам token, а его хеш;
  • срок действия token задаётся настройкой PASSWORD_RESET_TTL_MINUTES;
  • значение по умолчанию — 30 минут;
  • если SMTP настроен, пользователю отправляется письмо со ссылкой восстановления;
  • если SMTP не настроен, token может быть возвращён в ответе для локальной разработки.

Настройки окружения

  • PASSWORD_RESET_TTL_MINUTES — срок действия reset-token в минутах.
  • PASSWORD_RESET_LOGIN_URL — frontend URL страницы логина/сброса пароля.
  • PASSWORD_RESET_RETURN_TOKEN — разрешает возвращать reset-token в ответе.
  • SMTP_HOST — SMTP host.
  • SMTP_PORT — SMTP port.
  • SMTP_USERNAME — SMTP username.
  • SMTP_PASSWORD — SMTP password.
  • SMTP_FROM_EMAIL — email отправителя.
  • SMTP_FROM_NAME — имя отправителя.
  • SMTP_USE_TLS — использовать TLS.
  • SMTP_USE_SSL — использовать SSL.

Ошибки

КодТипОписание
400Bad RequestНевалидное тело запроса.
422Unprocessable EntityEmail отсутствует или не прошёл валидацию.
429Too Many RequestsСлишком много запросов восстановления.

Пример ответа при ошибке валидации

{
"error_description": "Invalid email"
}

1.7 POST /auth/password-reset/confirm

Подтверждает сброс пароля и устанавливает новый пароль.

Эндпоинт используется после того, как пользователь перешёл по ссылке из письма или ввёл reset-token вручную.

Эндпоинт публичный и не требует авторизации.

Request body (required)

  • token (string) — reset-token из письма или dev-ответа POST /auth/password-reset/request.
  • new_password (string) — новый пароль пользователя.

Пример запроса

POST /api/v1/auth/password-reset/confirm HTTP/1.1
Host: api.parktrack.live
Content-Type: application/json

{
"token": "Q9a2QY7V2uF9yJj...",
"new_password": "new_secret_456"
}

Response (200)

  • ok (boolean) — true, если пароль успешно изменён.

Пример ответа

{
"ok": true
}

Поведение

  • сервер хеширует переданный token и ищет его в таблице reset-token-ов;
  • token должен существовать;
  • token не должен быть использован ранее;
  • token не должен быть истёкшим;
  • пользователь, которому принадлежит token, должен существовать и быть активным;
  • после успешной смены пароля token помечается использованным;
  • повторное использование того же token невозможно.

Ошибки

КодТипОписание
400Bad RequestReset-token невалиден, уже использован или истёк.
422Unprocessable EntityНовый пароль не прошёл валидацию.
429Too Many RequestsСлишком много попыток подтверждения сброса.

Пример ответа при невалидном или истёкшем token

{
"error_description": "Reset token is invalid or expired"
}

Пример ответа при ошибке валидации нового пароля

{
"error_description": "Password must be at least 8 characters long"
}

1.8 POST /auth/logout

Завершает текущую сессию.

Headers

  • Authorization: Bearer <access_token>

Пример запроса

POST /api/v1/auth/logout HTTP/1.1
Host: api.parktrack.live
Authorization: Bearer <token>

Response (204) Тело ответа отсутствует.

Ошибки

КодТипОписание
401UnauthorizedТокен отсутствует, невалиден или истёк.

1.9 GET /auth/me

Возвращает информацию о текущем пользователе и его эффективных правах доступа.

Headers

  • Authorization: Bearer <access_token>

Response (200)

  • user_id (integer) — идентификатор пользователя.
  • email (string) — email пользователя.
  • full_name (string | null) — имя пользователя.
  • global_role (string) — глобальная роль пользователя.
  • permissions (string[]) — глобальные разрешения пользователя.
  • partner_memberships (PartnerMembership[]) — список членств в партнёрских организациях.

Пример запроса

GET /api/v1/auth/me HTTP/1.1
Host: api.parktrack.live
Authorization: Bearer <token>

Пример ответа (200)

{
"user_id": 123,
"email": "user@example.com",
"full_name": "Иван Петров",
"global_role": "user",
"permissions": [
"users.me.view",
"users.me.update",
"users.password.update",
"map.view",
"zones.view",
"occupancy.view",
"forecasts.view",
"routing.create",
"feedback.create"
],
"partner_memberships": [
{
"partner_id": 10,
"role": "partner_manager",
"permissions": [
"sources.create",
"sources.view",
"sources.update",
"cameras.create",
"cameras.view",
"cameras.update",
"zones.create",
"zones.view",
"zones.update"
],
"read_scope": "own_or_assigned",
"write_scope": "own_or_assigned",
"delete_scope": "own",
"is_active": true
}
]
}

Ошибки

КодТипОписание
401UnauthorizedТокен отсутствует, невалиден или истёк.

1.10 Требования к защищённым эндпоинтам

Каждый защищённый эндпоинт должен явно указывать:

  • требуется ли авторизация;
  • какие разрешения нужны для выполнения действия;
  • какая область доступа применяется к ресурсу.

Пример оформления в документации раздела:

  • Требуемые разрешения: cameras.update
  • Требуемая область доступа: write_scope должен включать целевую камеру

1.11 Совместимость

Auth API v1 фиксирует следующую модель для MVP:

  • используется только access_token;

  • refresh_token не используется;

  • публичная регистрация выполняется через POST /auth/register;

  • публичное восстановление пароля выполняется через:

    • POST /auth/password-reset/request;
    • POST /auth/password-reset/confirm;
  • карта доступна всем авторизованным пользователям;

  • доступ определяется ролями, разрешениями и областью доступа к данным.