Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Где хранить refresh token на фронтенде
Это один из ключевых вопросов безопасности при реализации аутентификации. Выбор места хранения влияет на защиту от различных типов атак и удобство использования.
Основные варианты хранения
1. HttpOnly Cookie (рекомендуемый подход)
Это наиболее безопасный вариант для большинства случаев.
// Backend отправляет refresh token в HttpOnly cookie
res.setHeader("Set-Cookie", "refreshToken=xyz; HttpOnly; Secure; SameSite=Strict; Path=/api/v1/auth; Max-Age=604800");
Преимущества:
- CSRF protection: При правильной конфигурации SameSite атаки CSRF блокируются
- XSS protection: JavaScript не может получить доступ к HttpOnly cookies
- Автоматическая передача: Браузер автоматически отправляет cookie с каждым запросом к доменуть
- Стандартный подход: Используется в большинстве production приложений
Недостатки:
- Требует поддержки корректной конфигурации CORS
- Сложнее тестировать
2. LocalStorage (НЕ рекомендуется)
// Хранение refresh token в localStorage
localStorage.setItem("refreshToken", token);
// Использование
const token = localStorage.getItem("refreshToken");
Недостатки:
- Уязвим для XSS атак: JavaScript может получить доступ
- Если на сайте XSS уязвимость, хакер получит refresh token
- Нет автоматической защиты от CSRF
Когда использовать:
- Только если нет альтернативы (старые браузеры)
- С дополнительными мерами защиты
3. SessionStorage
Аналогичен localStorage, но данные удаляются при закрытии браузера.
Недостатки:
- Те же проблемы с XSS
- Меньше удобства (токен теряется при обновлении)
4. Memory (оперативная память)
let refreshToken = null;
export function setRefreshToken(token) {
refreshToken = token;
}
export function getRefreshToken() {
return refreshToken;
}
Преимущества:
- Максимальная безопасность от XSS
- Недоступен для скриптов
Недостатки:
- Теряется при обновлении страницы
- Требует механизма восстановления
Рекомендуемая архитектура (Best Practice)
// 1. Backend отправляет refresh token в HttpOnly cookie
res.setHeader(
"Set-Cookie",
"refreshToken=xyz; HttpOnly; Secure; SameSite=Strict"
);
// 2. Frontend хранит только access token (можно в memory)
let accessToken = null;
// 3. Access token отправляется в Authorization header
headers["Authorization"] = `Bearer ${accessToken}`;
// 4. Refresh token автоматически отправляется браузером в cookie
// Никакой код на фронтенде не должен с ним работать напрямую
Процесс обновления токена
// Перехватчик для автоматического обновления access token
api.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
try {
// Отправляем POST запрос на refresh
// Refresh token автоматически отправится в cookie
const response = await api.post("/auth/refresh");
accessToken = response.data.accessToken;
// Повторяем оригинальный запрос
return api(error.config);
} catch (refreshError) {
// Refresh не удался - требуется заново авторизоваться
redirectToLogin();
}
}
return Promise.reject(error);
}
);
Конфигурация CORS и cookies
// Frontend запрос с credentials
fetch("/api/v1/auth/refresh", {
method: "POST",
credentials: "include", // ВАЖНО: отправляет cookies
headers: {
"Content-Type": "application/json"
}
});
// Или в axios
const api = axios.create({
baseURL: "https://api.example.com",
withCredentials: true // Включает отправку cookies
});
Дополнительные меры безопасности
- Secure флаг: Cookie отправляется только по HTTPS
- SameSite=Strict: Максимальная защита от CSRF
- Короткий TTL для refresh token: Обычно 7-30 дней
- Rotation: Обновлять refresh token при каждом использовании
- Rate limiting: Ограничить частоту запросов на refresh
Заключение
Для production приложений используй HttpOnly cookies для refresh token. Это обеспечивает оптимальный баланс между безопасностью и удобством. Access token можно хранить в памяти или localStorage, но refresh token НИКОГДА не должен быть доступен JavaScript коду.