docs
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
# `modules/auth` — авторизация
|
||||
|
||||
Три способа попасть в систему, всех их объединяет один и тот же JWT (`Claims { sub, tg_id, exp }`,
|
||||
живёт 10 минут — предполагается, что клиент кладёт его в cookie/заголовок и продлевает
|
||||
через повторный логин/бота, отдельного refresh-флоу нет):
|
||||
|
||||
1. **Telegram Login Widget** (`POST /auth/telegram`, `controller::auth_telegram_api`).
|
||||
Фронтенд получает от виджета подписанный payload, бэкенд проверяет HMAC-SHA256 подпись
|
||||
ключом `sha256(bot_token)` в **постоянное время** (`mac.verify_slice`, не строковое
|
||||
`!=`) — это защита от timing-атаки на подбор подписи (см. `service::verify_tg_widget_auth`).
|
||||
2. **Telegram-бот** (`/start [ref_code]`, обрабатывается в [`bot.rs`](../../bot.rs), не
|
||||
здесь) — вызывает тот же `AuthService::process_login`.
|
||||
3. **Ghost Protocol** (`POST /auth/seed/generate`, `POST /auth/seed/login`) — анонимный
|
||||
вход без привязки к Telegram. Сервер генерирует случайный 16-символьный seed,
|
||||
хеширует его Argon2 с **фиксированной** солью из `ARGON_SALT` (детерминированно —
|
||||
иначе логин никогда не совпадёт с хешем, сохранённым при регистрации) и хранит только
|
||||
хеш. Seed невосстановим: его теряет — теряет аккаунт.
|
||||
|
||||
## Гварды (`guard.rs`)
|
||||
|
||||
- `auth_guard` — достаёт JWT из `Authorization: Bearer` **или** из cookie `nrxp_token`,
|
||||
валидирует подпись, подтягивает юзера из БД и кладёт его в `req.extensions()` для
|
||||
контроллеров. Для мутирующих запросов (`POST/PUT/PATCH/DELETE`), пришедших **через
|
||||
cookie**, дополнительно проверяет `Origin`/`Referer` — это CSRF-защита. Bearer-запросы
|
||||
её не проходят и не должны: подделать `Authorization`-заголовок с чужого origin браузер
|
||||
не даст, поэтому CSRF для них неактуален.
|
||||
- `admin_guard` — должен идти **после** `auth_guard` в цепочке слоёв (читает юзера из
|
||||
extensions). Пропускает, если `tg_id` юзера совпадает с `ADMIN_TG_ID` из `.env` или его
|
||||
`role == "admin"`.
|
||||
|
||||
## Sybil-защита
|
||||
|
||||
Триал (`billing::activate_trial`) намеренно недоступен Ghost-аккаунтам — иначе
|
||||
генерация нового seed была бы бесплатным и безлимитным способом штамповать VPN-доступ.
|
||||
Подробности инцидента и фикса — в [`SECURITY_AUDIT.md`](../../../SECURITY_AUDIT.md).
|
||||
@@ -1,3 +1,6 @@
|
||||
//! Авторизация: Telegram Login Widget, анонимный "Ghost Protocol" (вход по seed-фразе)
|
||||
//! и JWT-гварды (`auth_guard`, `admin_guard`). См. README.md рядом с этим файлом.
|
||||
|
||||
pub mod controller;
|
||||
pub mod guard;
|
||||
pub mod service;
|
||||
|
||||
Reference in New Issue
Block a user