Ответ
Refresh Token — это долгоживущий, одноразовый токен, используемый для безопасного получения новой пары Access/Refresh токенов без необходимости повторного ввода учётных данных пользователем (логина/пароля). Это ключевой компонент для баланса между безопасностью и удобством.
Архитектура и поток работы:
-
Первая аутентификация: Пользователь логинится, сервер возвращает:
- Access Token (JWT): Короткоживущий (15-30 мин.), содержит claims (например,
user_id,roles), подписан. Клиент отправляет его в заголовкеAuthorization: Bearer <token>для доступа к API. - Refresh Token: Долгоживущий (дни, недели), случайная строка, хранится только на сервере (в БД или кэше) в связке с идентификатором пользователя.
- Access Token (JWT): Короткоживущий (15-30 мин.), содержит claims (например,
-
Обновление: Когда Access Token истекает, клиент отправляет Refresh Token на специальный эндпоинт (
/auth/refresh). Сервер:- Проверяет его наличие и валидность в своём хранилище.
- Инвалидирует старый Refresh Token (удаляет из БД).
- Генерирует и возвращает новую пару Access/Refresh токенов.
Пример кода (псевдокод логики на стороне сервера):
# Эндпоинт /auth/refresh
def refresh_token_endpoint(refresh_token_from_client):
# 1. Поиск и проверка токена в БД
token_record = db.find_refresh_token(refresh_token_from_client)
if not token_record or token_record.expired:
return 401, "Invalid refresh token"
# 2. Инвалидация использованного токена
db.delete_refresh_token(refresh_token_from_client)
# 3. Генерация новой пары
user_id = token_record.user_id
new_access_token = create_jwt(user_id, expires_in='15m')
new_refresh_token = generate_secure_random_string()
db.save_refresh_token(user_id, new_refresh_token, expires_in='7d')
# 4. Отправка новой пары клиенту
return {
"access_token": new_access_token,
"refresh_token": new_refresh_token
}
Зачем это нужно? Без Refresh Token пришлось бы либо делать Access Token долгоживущим (опасно при утечке), либо заставлять пользователя логиниться каждые 15 минут. Refresh Token позволяет отозвать доступ (удалив его на сервере) и минимизирует время жизни основного Access Token.