UnicoreCMS

Авторизация

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-токен так не убрать, он работает, пока не кончится его короткий срок.

Содержание