Как поддерживаются сессии и обновление токенов
Что проверяют
Понимаете ли вы разницу между серверной сессией и самодостаточным токеном и можете ли объяснить, как отозвать доступ в каждой схеме. Следом обычно спрашивают, где клиент хранит токены и что будет, если refresh-токен украли.
Как отвечать
Две схемы и их цена:
- серверная сессия: случайный идентификатор из
crypto/randдлиной не меньше 128 бит, в cookie сHttpOnly,SecureиSameSite=Lax, сама сессия лежит в Redis с TTL. Отзыв мгновенный: удалили ключ, и пользователь разлогинен. Цена: запрос к хранилищу на каждый вызов; - JWT: подпись проверяется без обращения к базе, поэтому схема удобна между сервисами. Платите тем, что выданный токен действует до
exp, и отозвать его раньше можно только списком отозванныхjti.
Отсюда стандартная связка: короткий access-токен на несколько минут и длинный refresh-токен. Refresh лучше делать непрозрачной случайной строкой, в базе хранить только её хэш, а клиенту отдавать в HttpOnly cookie с Path, ограниченным ручкой обновления. При каждом обновлении выдаётся новая пара, а старый refresh помечается использованным, это ротация. Если использованный токен приходит снова, это признак кражи: отзывается вся цепочка, и пользователь входит заново.
В Go проверка живёт в middleware вокруг http.Handler: достать токен, проверить, положить пользователя в context.WithValue с неэкспортируемым типом ключа. Актуальная библиотека github.com/golang-jwt/jwt/v5, в ней RegisteredClaims и опция парсера jwt.WithValidMethods, которая не примет токен с чужим алгоритмом. Упомяните гонку двух вкладок при обновлении: её лечат коротким окном, когда старый refresh ещё принимается, или единым обновлением на клиенте.
Где спотыкаются
Берут github.com/dgrijalva/jwt-go из старых статей. Репозиторий заброшен, в нём известная уязвимость, поддерживаемый форк это golang-jwt/jwt.
Не проверяют алгоритм в функции выдачи ключа и принимают любой alg из заголовка. Это открывает атаку с подменой алгоритма подписи.
Хранят токены в localStorage и делают access-токен на сутки, «чтобы реже обновлять». Любая XSS уносит долгоживущий токен, а отозвать его до истечения нечем.