← Назад к вопросам

На каждый ли запрос нужно прикреплять refresh token

2.0 Middle🔥 112 комментариев
#JavaScript Core

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Механизм работы Refresh Token и стратегия его отправки

Вопрос о том, нужно ли прикреплять refresh token на каждый запрос, затрагивает фундаментальные принципы безопасности и проектирования современных систем аутентификации. Ответ однозначен: нет, на каждый запрос refresh token отправлять категорически не нужно и небезопасно. Это распространённое заблуждение, возникающее из-за непонимания разделения ролей между access token и refresh token.

Разделение ответственности: Access Token vs Refresh Token

  • Access Token (токен доступа): Это ваш "пропуск". Короткоживущий (минуты/часы), прикрепляется к каждому запросу, требующему авторизации (обычно в заголовке Authorization: Bearer <token>). Его задача — дать серверу быструю возможность проверить ваши права. Если он украден — окно уязвимости невелико.
  • Refresh Token (токен обновления): Это ваш "ключ для получения новых пропусков". Долгоживущий (дни, недели, даже месяцы), используется крайне редко — только для получения новой пары access/refresh token, когда access token истёк. Он хранится максимально безопасно и никогда не путешествует по сети при каждом обращении к API.

Отправка refresh token с каждым запросом превращает его по сути в long-lived access token, сводя на нет все его преимущества безопасности и полностью нарушая принцип разделения.

Почему это критически опасно?

  1. Резкое увеличение поверхности атаки: Refresh token появляется в сетевом трафике в сотни раз чаще, что значительно повышает риск его перехвата (через MITM-атаки, логирование).
  2. Потеря смысла его существования: Если refresh token можно перехватить так же легко, как и access token, зачем вообще нужны два токена? Вся модель безопасности рушится.
  3. Невозможность безопасного отзыва: Одним из главных преимуществ является возможность отозвать refresh token (например, при потере устройства), не меняя немедленно пароль пользователя. Если он скомпрометирован из-за постоянной передачи, отзыв становится "догоняющей" мерой, а не упреждающей.

Правильный паттерн работы с токенами

Типичный и безопасный flow выглядит так:

  1. Первичная аутентификация: Пользователь вводит логин/пароль -> получает пару access token (AT) и refresh token (RT).
  2. Работа с API: Клиент отправляет только AT в заголовке каждого авторизованного запроса.
GET /api/protected-data HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Host: api.example.com
  1. Обнаружение просрочки AT: Сервер отвечает 401 Unauthorized с указанием на истёкший токен.
  2. Запрос обновления пары: Клиент отправляет единственный специальный запрос на эндпоинт обновления (например, POST /api/auth/refresh), передавая в теле или безопасным способом только refresh token.
// Пример запроса на обновление (в коде клиента)
async function refreshTokens() {
  const response = await fetch('/api/auth/refresh', {
    method: 'POST',
    credentials: 'include', // Или отправка RT в теле запроса, но НЕ в заголовке Authorization
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      refreshToken: storedRefreshToken // Токен, хранимый в secure storage (httpOnly cookie, Keychain, Keystore)
    })
  });
  const newTokens = await response.json();
  // Сохраняем новый AT и, возможно, новый RT
  secureStore.set('accessToken', newTokens.access);
}
  1. Получение новой пары: Сервер проверяет RT, если он валентен и не отозван — выдаёт новую пару AT и (часто) новый RT. Старый RT при этом инвалидируется ("rotation").
  2. Повтор запроса с новым AT: Клиент повторяет первоначальный запрос с новым access token.

Где и как безопасно хранить refresh token?

Так как он используется редко, но крайне ценен, подход к его хранению должен быть строже:

  • Backend (серверные приложения): В безопасном, зашифрованном хранилище, связанном с сессией пользователя.
  • Web-клиент (браузер): Наиболее безопасный способ — сохранение в httpOnly, Secure, SameSite=Strict cookie. Это защищает его от доступа JavaScript (атаки XSS).
  • Мобильные/Desktop приложения: Использование защищённых хранилищ ОС: Keychain (iOS/macOS), Keystore (Android), Credential Manager (Windows).

Итог и ключевое правило

Refresh token — это секретный ключ для продления сессии, а не пропуск для доступа к данным. Его следует беречь как пароль, использовать как можно реже (только по прямому назначению) и никогда не отправлять в заголовке Authorization рутинных запросов. Прикреплять его нужно исключительно в одном сценарии — при вызове специального эндпоинта /refresh для получения новой пары токенов, после чего он должен быть безопасно уничтожен на клиенте и заменён новым. Соблюдение этого правила — основа безопасной JWT-авторизации.