API авторизации и сессии
Вход построен на короткоживущем запросе, подтверждении в Telegram и доказательстве владения исходным браузером. Переданный клиентом Telegram ID не используется как подтверждение личности.
В этой статье
Начало входа#
POST /api/auth/telegram/start принимает пустой JSON {}. Требует точного Origin приложения и настроенного бота. Сервер создаёт challenge на 300 секунд и защищённую cookie browser proof.
Ответ 201 содержит challengeId, code, expiresAt и telegramUrl. Cookie доказательства не входит в deep link и недоступна JavaScript. Лимит — 6 запусков в минуту по хешу адреса.
const response = await fetch('/api/auth/telegram/start', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: '{}'
});
const challenge = await response.json();
// Покажите code и ссылку telegramUrl пользователю.Ожидание подтверждения#
POST /api/auth/telegram/complete принимает {challengeId}. Требует Origin и proof cookie исходного браузера. Пока пользователь не подтвердил запрос, сервер возвращает 202 {status: "pending"}.
После подтверждения возвращается 200: status=authenticated, user, csrfToken и expiresAt. Сессия выдаётся один раз. Просроченный запрос даёт 410, использованный или отменённый — 409.
const response = await fetch('/api/auth/telegram/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ challengeId: challenge.challengeId })
});
if (response.status === 202) {
// Повторите проверку с паузой; не создавайте новый challenge.
}Чтение сессии#
GET /api/auth/me без действующей сессии возвращает 200 {authenticated:false}. Авторизованный ответ содержит пользователя, CSRF и время окончания сессии.
Cookie __Host-kevmi-session действует до 24 часов, имеет Secure, HttpOnly, SameSite=Lax и Path=/. В базе хранится SHA-256 токена. Значение cookie нельзя читать или подменять через форму профиля.
Изменения аккаунта#
Запросы изменения требуют сессию, точный Origin и X-CSRF-Token текущей сессии. Sec-Fetch-Site: cross-site отклоняется. Сервер не предоставляет произвольный CORS-доступ.
Для чтения собственного аккаунта ID пользователя в теле не нужен: сервер получает его из сессии. Отсутствующая запись и чужая запись не раскрывают различающиеся сведения.
Завершение входа#
POST /api/auth/logout завершает текущую сессию и очищает cookie. Требует Origin и CSRF; тело не читается. Команда /logout в Telegram дополнительно завершает все сессии аккаунта.
При смене домена cookie не переносятся автоматически. Обновите APP_ORIGIN и webhook бота, затем выполните новый вход.