Ответ
JWT-токен хранится на стороне клиента. Выбор места хранения — это компромисс между удобством и безопасностью. Основные варианты и связанные с ними риски:
-
localStorage
/sessionStorage
- Описание: Хранилище в браузере, доступное через JavaScript.
sessionStorage
очищается при закрытии вкладки. - Плюс: Простота реализации.
- Минус: Уязвимость к XSS-атакам (Cross-Site Scripting). Если злоумышленник внедрит свой скрипт на страницу, он сможет прочитать и украсть токен.
// Сохранение токена localStorage.setItem('jwt_token', 'your.jwt.token');
// Получение токена для заголовка Authorization const token = localStorage.getItem('jwt_token');
- Описание: Хранилище в браузере, доступное через JavaScript.
-
HttpOnly
Cookie- Описание: Cookie, которые автоматически отправляются с каждым HTTP-запросом на тот же домен, но недоступны для чтения из JavaScript на клиенте.
- Плюс: Встроенная защита от XSS-атак, так как скрипты не могут прочитать токен.
- Минус: Уязвимость к CSRF-атакам (Cross-Site Request Forgery). Требует дополнительных мер защиты (атрибут
SameSite=Strict
илиLax
, CSRF-токены).# Пример установки cookie в ответе (Flask) response.set_cookie( 'access_token', 'your.jwt.token', httponly=True, # Запрещает доступ из JS secure=True, # Отправка только по HTTPS samesite='Strict' # Защита от CSRF )
Рекомендуемый подход (Token-Based Authentication)
Наиболее безопасной считается комбинация из двух токенов:
- Access Token (короткоживущий): Хранится в памяти приложения (например, в переменной JavaScript). Используется для авторизации запросов. Его короткий срок жизни (5-15 минут) минимизирует ущерб в случае кражи.
- Refresh Token (долгоживущий): Хранится в
HttpOnly
cookie. Используется исключительно для получения новогоaccess token
, когда старый истекает.
Этот подход сочетает защиту от XSS (токен не в localStorage
) и снижает риски CSRF (критичные операции требуют access token
, который не отправляется автоматически как cookie).