Авторизация
JWT, refresh, сессии и двухфакторка
Пользователь входит по паре токенов: короткий access и длинный refresh. Сроки задаёте в .env (JWT_EXPIRES, JWT_REFRESH_EXPIRES).
Вход
POST /auth/login
Content-Type: application/json
{
"username_or_email": "Notch",
"password": "…",
"totp": "123456"
}totp нужен только тем, у кого включена двухфакторка. Поле для входа одно, в него подойдёт и ник, и почта.
Ответ:
{
"accessToken": "eyJ…",
"refreshToken": "eyJ…",
"user": { "uuid": "…", "username": "Notch", "real": 0, "virtual": 0 }
}reCAPTCHA
Если в .env заполнены ключи reCAPTCHA, заголовок recaptcha с токеном придётся слать при входе, регистрации, сбросе пароля и активации подарка. Действия называются login, register, reset, verify, gift. Имя действия указывают при генерации токена на клиенте.
Регистрация
POST /auth/register
{
"username": "Notch",
"email": "notch@example.com",
"password": "…",
"ref": "PriglashayushiyNick"
}ref необязателен, это ник пригласившего для реферальной программы.
Ограничение: 5 регистраций в час с адреса. У ника своё правило: латиница, цифры и _, то есть всё, что примет Minecraft. Пароль проверяют только по длине.
Если в настройках сайта включено подтверждение почты, аккаунт создастся неактивированным и на почту уйдёт код.
Обновление токена
POST /auth/refresh
{ "refresh_token": "eyJ…" }Возвращает новую пару. Refresh-токен по умолчанию ротируется, старый становится недействительным. Если запросы идут параллельно, обновляйте токен один раз и ждите общего результата, иначе вторая попытка предъявит уже сожжённый токен.
Во фронте так и сделано, несколько ответов 401 ждут одного обновления.
Текущий пользователь
GET /auth/me
Authorization: Bearer <accessToken>Ручка работает и для неактивированных аккаунтов, чтобы сайт показал экран «подтвердите почту», а не выкинул на логин.
Сессии
Каждый refresh-токен — это сессия с устройством и IP. Их видно в кабинете:
| Метод | Путь | Что делает |
|---|---|---|
POST | /auth/sessions/me | Список сессий, текущая помечена |
DELETE | /auth/sessions/:id | Закрыть одну |
DELETE | /auth/sessions_other | Закрыть все, кроме текущей |
DELETE | /auth/sessions_all | Закрыть все |
При входе с незнакомого устройства приходит письмо с IP. Отключить это нечем.
Активация почты
| Метод | Путь | Что делает |
|---|---|---|
POST | /auth/verify | Подтвердить код из письма |
GET | /auth/resend | Выслать код заново, 3 раза за 10 минут |
Код перебором не подобрать, попыток всего 10 за 10 минут.
Сброс пароля
POST /auth/reset { "email": "notch@example.com" }
POST /auth/password { "hash": "…", "password": "…" }Первая отправляет письмо со ссылкой, вторая меняет пароль по хешу из этой ссылки. Лимит здесь тот же, 5 запросов в час с адреса.
У второй ручки есть флаг close: он заодно закроет все сессии пользователя. Пригодится, когда пароль меняют из-за угона.
Опять `TRUST_PROXY`
Все лимиты в этом разделе считаются по IP клиента. За прокси без настроенного TRUST_PROXY они схлопываются в один общий счётчик, и первый же пользователь исчерпает лимит на всех.
Двухфакторная аутентификация
TOTP, подойдёт любое приложение-аутентификатор.
| Метод | Путь | Что делает |
|---|---|---|
GET | /cabinet/2fa/generate | Выдать секрет и QR-код |
POST | /cabinet/2fa/enable | Включить, подтвердив кодом |
POST | /cabinet/2fa/disable | Выключить |
Секрет хранится в базе зашифрованным, резервных кодов нет. Если игрок потерял телефон, двухфакторку снимает администратор из карточки пользователя.
Выход
POST /auth/logout
{ "refresh_token": "eyJ…" }Отзывает конкретный refresh-токен. Access-токен так не убрать, он работает, пока не кончится его короткий срок.