Как правильно хранить токены аутентификации на стороне сервера?

«Как правильно хранить токены аутентификации на стороне сервера?» — вопрос из категории Тестирование безопасности, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Безопасное хранение токенов на сервере — критически важная задача. Основной принцип: никогда не хранить секретные данные (как оригинальные токены или пароли) в открытом виде.

Лучшие практики хранения:

  1. Использовать хеширование (для токенов сессии/рефреш-токенов):

    • Сохранять в базе данных не сам токен, а его криптографический хеш (например, с помощью SHA-256 или bcrypt). При проверке хешируется входящий токен и сравнивается с сохранённым хешом.
      -- Пример структуры таблицы для сессий
      CREATE TABLE user_sessions (
      id SERIAL PRIMARY KEY,
      user_id INT NOT NULL,
      token_hash VARCHAR(64) NOT NULL UNIQUE, -- Храним хеш токена
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      expires_at TIMESTAMP NOT NULL
      );
  2. Использовать подписанные токены (например, JWT):

    • Сервер не хранит состояние токена. Вместо этого он выпускает токен, подписанный секретным ключом. Серверу нужно хранить только этот секретный ключ для проверки подписи.
    • Преимущество: Не требует запросов к базе данных для проверки каждого запроса (stateless).
    • Недостаток: Сложнее отозвать токен до истечения его срока жизни (exp claim).
  3. Применять безопасные хранилища:

    • Для хешей или ключей подписи использовать защищённые базы данных с ограничением доступа.
    • Для временных данных (как кеш сессии) можно использовать Redis или Memcached с настройкой TLS и паролем.
  4. Строго ограничивать срок жизни:

    • Использовать короткоживущие access-токены (минуты/часы) и механизм refresh-токенов для их обновления. Refresh-токены должны храниться максимально безопасно (как в п.1) и иметь строгий механизм отзыва.

Главный риск при хранении токенов в БД — утечка базы данных. Хеширование минимизирует этот риск, так как исходный токен восстановить из хеша невозможно.