Files
docs/domains/authentication/overview.md
T
ksv741 97069d6f6d
Docs security / security (pull_request) Successful in 6s
Docs verify / verify (pull_request) Successful in 11s
Conventional commits / commits (pull_request) Successful in 16s
Docs security / security (push) Successful in 9s
Docs verify / verify (push) Successful in 10s
docs: make documentation checks self-contained
2026-09-15 20:45:40 +03:00

9.2 KiB
Raw Permalink Blame History

Аутентификация и сессии

Аутентификация связывает локального пользователя с его сессией WealthLedger. Она открывает доступ к приложению; доступ к брокерским данным определяется отдельным подключением T-Bank. Backend проверяет учётные данные и управляет сессиями, frontend восстанавливает состояние входа и выбирает доступные маршруты.

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

Пользователь регистрируется или входит по email и паролю. Регистрация сразу создаёт первую сессию. Внешние пробелы email удаляются, буквы приводятся к нижнему регистру. Backend требует пароль не короче 12 символов и не длиннее 72 UTF-8 байтов.

Известное расхождение: сохранённое требование регистрации и проверка в форме frontend считают нижнюю границу в UTF-8 байтах, а backend — в символах. Не-ASCII пароль может пройти форму и получить отказ API. Это не принятое изменение password policy; требуется отдельное согласованное решение о проверке пароля и подтверждение полного HTTP-потока.

Access token действует 15 минут и хранится только в памяти браузера. Refresh token имеет серверный срок 7 дней, заменяется при восстановлении сессии и передаётся в cookie refresh_token с httpOnly и SameSite=Lax. Сроки определены в спецификации сессий и ADR 006.

После перезагрузки SPA получает новый access token через refresh-cookie. Пока результат неизвестен, пользователь видит нейтральный skeleton каркаса без преждевременного показа public или protected содержимого. После завершения восстановления приложение выбирает доступный маршрут.

Все маршруты, кроме /login и /register, требуют сессию. После входа пользователь возвращается на исходный внутренний маршрут, если он был. Logout доступен в настройках: frontend очищает локальную сессию независимо от состояния сети, а backend отзывает серверную сессию при предъявлении её действительного refresh-cookie.

Восстановление сессии

Динамическая схема показывает восстановление после reload между SPA, auth API и локальным хранилищем сессий. SQLite здесь — файл базы backend.

sequenceDiagram
  participant F as React SPA
  participant B as Backend API
  participant D as Локальная SQLite
  Note over F: Reload: access token в памяти отсутствует
  F->>B: Refresh с httpOnly cookie
  B->>D: Проверить Session и текущий hash token
  alt Действительная сессия, ротация выиграна
    B->>D: Атомарно заменить hash и срок
    B-->>F: Access token, профиль, новая refresh-cookie
    F->>B: Protected request с Bearer
  else Cookie нет или refresh отклонён
    B-->>F: 401 и очистка cookie
    Note over F: Готовое неавторизованное состояние
  end

В одном экземпляре frontend одновременные refresh используют один незавершённый запрос. Между вкладками используется Web Locks, если браузер его поддерживает. Backend всё равно защищает ротацию атомарно: координация браузеров не заменяет серверную проверку.

Обычный защищённый запрос с 401 UNAUTHORIZED проходит refresh и один повтор через общий транспорт; auth endpoints из этого цикла исключены. Само истечение access token не запускает фоновый таймер refresh.

HTTP-граница

Endpoints, статусы и формы публичных ответов определяет backend OpenAPI; граница производного клиента описана в HTTP API. Refresh-cookie ограничена auth API. Признак Secure зависит от режима окружения: в development допускается локальный HTTP, в остальных режимах Secure-cookie требует защищённого соединения.

HTTP-ошибка и транспортная ошибка refresh одинаково завершают начальное восстановление готовым неавторизованным состоянием. При refresh после защищённого 401 frontend очищает сессию в памяти и query cache, сохраняя исходный 401 для перехода ко входу. Общая форма ошибок и известное расхождение деталей валидации находятся в HTTP API.

Ограничения

Описанный auth flow ограничен регистрацией, входом, восстановлением сессии и logout. Подтверждение email, восстановление или смена пароля, смена email, удаление аккаунта, список устройств, logout всех устройств и rate limit попыток входа не входят в эту реализованную возможность. Access token может оставаться действительным до 15 минут после logout.

Если несколько клиентов одновременно предъявляют один действительный refresh token, сервер завершает одну ротацию успешно, остальные запросы получают 401. Сессия победившего запроса остаётся действительной. Уже заменённый refresh token также даёт 401, но сам по себе не отзывает сессию: механизм не хранит историю token или grace-window, чтобы отличить конкурентный запрос от replay. Это ограничение и его причины сохранены в ADR 009.

Refresh-cookie не задаёт собственные maxAge или expires. Семидневный серверный срок refresh token не является обещанием сохранения входа после закрытия браузера.

Ответственность и проверка

Backend проверяет учётные данные и tokens, хранит состояние Session и атомарно выполняет ротацию. Frontend управляет состоянием входа, восстановлением после reload и доступностью экранов; общий HTTP-транспорт передаёт Bearer token и выполняет описанный refresh/retry.

Проверки конкурентной ротации, браузерного состояния и транспорта охватывают разные границы. Их изолированная проверка не заменяет полный HTTP-поток и проверку атомарности с реальной изолированной базой.

Согласованное поведение находится в workspace-спецификации User authentication. Правила начального ожидания — в состояниях интерфейса.