Где хранится токен?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Где хранится токен?
Вопрос хранения аутентификационного токена — один из ключевых в веб-безопасности. Я расскажу о различных подходах и их особенностях.
Основные места хранения
1. LocalStorage
Historically популярное место для хранения JWT токенов на клиенте.
// Сохранение токена
localStorage.setItem("authToken", token);
// Получение токена
const token = localStorage.getItem("authToken");
// Использование в запросе
fetch("/api/data", {
headers: {
"Authorization": `Bearer ${token}`
}
});
Минусы:
- Уязвим для XSS (Cross-Site Scripting) атак
- JavaScript имеет полный доступ через localStorage
- Если злоумышленник инжектит скрипт, он может украсть токен
Плюсы:
- Прост в использовании
- Доступен для всех запросов
2. SessionStorage
Похож на localStorage, но удаляется при закрытии вкладки.
sessionStorage.setItem("authToken", token);
const token = sessionStorage.getItem("authToken");
Особенности:
- Более безопасен, чем localStorage (удаляется при закрытии)
- Все еще уязвим для XSS
- Не работает между вкладками
3. HttpOnly Cookies (РЕКОМЕНДУЕТСЯ)
Это лучший способ для веб-приложений благодаря встроенной защите.
// На сервере (Node.js/Express)
res.cookie("authToken", token, {
httpOnly: true, // JavaScript НЕ может получить доступ
secure: true, // Только HTTPS
sameSite: "Strict", // Защита от CSRF
maxAge: 3600000 // 1 час
});
В браузере:
// Токен автоматически отправляется в каждом запросе
fetch("/api/data", {
credentials: "include" // Важно: отправляет cookies
});
// Получить токен в JavaScript - НЕВОЗМОЖНО (это фишка!)
Плюсы:
- Защищен от XSS (JavaScript не может получить доступ)
- Автоматически отправляется в каждом запросе
- Защита от CSRF благодаря sameSite флагу
- Защита от сниффинга благодаря secure флагу (только HTTPS)
Минусы:
- Требует правильную настройку CORS
- Сложнее при работе с API и мобильными приложениями
4. Refresh Token Pattern
Сочетание short-lived access token + long-lived refresh token.
// Access token (short-lived, например 15 минут)
// Хранится в httpOnly cookie или memory
// Refresh token (long-lived, например 7 дней)
// Хранится в httpOnly cookie
// Логика обновления
async function getValidAccessToken() {
// Проверяем, не истек ли access token
if (isExpired(accessToken)) {
const response = await fetch("/api/refresh", {
method: "POST",
credentials: "include" // Отправляем refresh token
});
const { accessToken: newToken } = await response.json();
// Сохраняем новый access token
}
return accessToken;
}
Преимущества:
- Если access token украден, он действителен только 15 минут
- Refresh token остается безопасным в httpOnly cookie
- Меньше данных передается в каждом запросе
5. Memory (в Runtime)
Для SPA приложений можно хранить токен в переменной памяти.
let accessToken = null;
function setToken(token) {
accessToken = token;
}
function getToken() {
return accessToken;
}
// При перезагрузке страницы токен теряется
// Используется с refresh token для восстановления
Плюсы:
- Максимальная безопасность от XSS (не в storage)
- Недоступен из девтулс
Минусы:
- Теряется при перезагрузке
- Требует refresh token для восстановления
Рекомендации по использованию
Для веб-приложений (Web):
- Используй httpOnly cookies для хранения refresh token
- Храни access token в memory или httpOnly cookie
- Обязательно используй secure и sameSite флаги
- Реализуй CSRF protection (CSRF token в headers)
Для мобильных приложений:
- Используй защищенное локальное хранилище (Keychain для iOS, Keystore для Android)
- Не используй localStorage/sessionStorage
- Использование httpOnly cookies невозможно
Для SPA с максимальной безопасностью:
- Refresh token в httpOnly cookie
- Access token в memory
- При перезагрузке — восстановление через refresh endpoint
Итог
HttpOnly cookies остаются золотым стандартом для веб-приложений благодаря защите от XSS. Комбинирование с refresh token pattern обеспечивает оптимальный баланс безопасности и удобства.