Где безопасно хранить токены аутентификации в браузере?

«Где безопасно хранить токены аутентификации в браузере?» — вопрос из категории Безопасность, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Наиболее безопасный способ — использование HttpOnly, Secure, SameSite cookies. Это защищает от атак межсайтового скриптинга (XSS) и межсайтовой подделки запросов (CSRF).

Пример установки защищённой куки на бэкенде (Node.js/Express):

res.cookie('auth_token', signedJwtToken, {
    httpOnly: true,    // Недоступна из JavaScript
    secure: true,      // Передаётся только по HTTPS
    sameSite: 'strict', // Защита от CSRF
    maxAge: 24 * 60 * 60 * 1000 // 1 день
});

Почему не LocalStorage/SessionStorage?

  • Они доступны через JavaScript, что делает токен уязвимым при XSS-атаке.
  • Злоумышленный скрипт может прочитать токен и отправить его на свой сервер.

Современный подход для SPA (Single Page Application):

  1. Access Token: Короткоживущий (минуты), хранится в памяти JavaScript (переменная, замыкание). При обновлении страницы теряется, и приложение запрашивает новый через специальный endpoint.
  2. Refresh Token: Долгоживущий, хранится строго в HttpOnly куке. Используется для получения новой пары access/refresh токенов.

Пример потока:

  1. Пользователь логинится, бэкенд устанавливает refresh_token в HttpOnly куку и возвращает access_token в теле ответа.
  2. SPA сохраняет access_token в памяти и использует для API-запросов.
  3. Когда access_token истекает, SPA отправляет запрос на /refresh (кука refresh_token отправится автоматически).
  4. Бэкенд валидирует refresh_token и выдаёт новую пару.

Этот подход минимизирует риски утечки долгоживущих учётных данных.