Токены OAuth 2.0 и OpenID Connect
В OIDC-интеграции используются три разных токена. Их нельзя взаимозаменять.
| Токен | Назначение |
|---|---|
| ID Token | Сообщает приложению результат аутентификации и данные пользователя |
| Access Token | Даёт доступ к защищённому API |
| Refresh Token | Позволяет получить новый Access Token без повторного входа |
Стандарт
ID Token относится к OIDC. Access Token относится к OAuth 2.0. Refresh Token используется для обновления сессии, если это разрешено flow и scopes.
Практика
API должно проверять подпись Access Token, а также iss, aud и exp. Декодирование JWT
не подтверждает его подлинность. ID Token не следует отправлять в API вместо Access Token.
Путь токенов в приложении
После входа приложение обычно делает следующее:
- получает authorization code на callback;
- обменивает его на ID Token и Access Token;
- читает идентичность из проверенного ID Token;
- создаёт локальную сессию;
- передаёт Access Token в API;
- при истечении срока запрашивает новый Access Token через Refresh Token;
- при недействительном Refresh Token запускает новый вход.
authorization code -> ID Token + Access Token
|
v
запрос к API
|
v
Refresh Token -> новый Access Token
Какой токен где использовать
ID Token можно использовать приложению для построения профиля вошедшего пользователя после проверки. Его не следует отправлять в API вместо Access Token.
Access Token предъявляется resource server. API проверяет подпись, issuer, audience и срок действия. После этого API отдельно проверяет, может ли субъект выполнить операцию.
Refresh Token не отправляется в каждый API-запрос. Он используется только для token endpoint и должен храниться в защищённом контексте. В браузере не выбирайте хранилище токенов автоматически: оцените XSS-риски и используйте SDK или безопасную серверную сессию.
JWT и проверка
JWT состоит из header, payload и signature. Header и payload кодируются, но не шифруются. Поэтому любой, кто получил JWT, может прочитать его содержимое. Это не означает, что он может создать настоящий токен.
Подробно устройство JWT, роль kid и получение публичных ключей из JWKS разобраны в статье
JWT и JWKS.
Проверка должна включать:
- подпись подходящим ключом из JWKS;
- разрешённый алгоритм;
issожидаемого issuer;audвашего client или API;expи, при необходимости,iat;- соответствие типа токена месту использования.
Типичные ошибки
Отправить ID Token в API
API должен принимать Access Token, выпущенный для него. Похожая структура JWT не делает ID Token токеном доступа.
Только декодировать JWT
JSON.parse после Base64-декодирования не проверяет подпись. Используйте OIDC-библиотеку
или валидатор JWT с JWKS.
Хранить Refresh Token в репозитории
Refresh Token является credential. Его нельзя писать в логи, тестовые fixtures, screenshots и Git. При утечке отзовите сессию или ключи согласно вашему процессу безопасности.
Как проверить результат
- ID Token используется для идентичности, Access Token — для API;
- API отклоняет изменённую подпись;
- API отклоняет неправильные
issиaud; - после истечения Access Token SDK выполняет refresh;
- после удаления Refresh Token приложение возвращает пользователя на вход.
Срок действия и запас на обновление
Access Token может истечь между проверкой времени на клиенте и фактическим запросом к API. Поэтому SDK обновляет его с запасом, а API всё равно должно обрабатывать ответ о недействительном токене. Не полагайтесь только на таймер в интерфейсе.
Refresh Token не делает сессию бессрочной. Он тоже имеет срок действия и может быть отозван. Если refresh завершился ошибкой, приложение очищает локальную сессию и предлагает повторный вход. Бесконечные повторы refresh создают цикл запросов и скрывают настоящую причину ошибки.
Где хранить токены
Для Confidential-приложения предпочтительна серверная сессия, в которой браузер получает только защищённую cookie. Для SPA решение сложнее: любой токен, доступный JavaScript, потенциально доступен при XSS. Используйте SDK, Content Security Policy, безопасную обработку пользовательского HTML и не выводите токены в console.
Для API токен нужно передавать по HTTPS. Не помещайте его в query string: URL попадает в историю, логи, proxy и системы аналитики.
Access Token и аудит API
API должен отвечать на два разных вопроса: «токен настоящий и предназначен этому API?»
и «может ли субъект выполнить действие?». Первый вопрос решается JWT/OIDC validation.
Второй — приложением: по sub, scopes, ролям, владельцу ресурса или другой policy.
Что делать при утечке
Не публикуйте значение токена даже в issue или скриншоте. Отзовите сессию или Refresh Token,
замените скомпрометированный client secret, проверьте логи и перевыпустите credentials.
Замена токена в документации на ACCESS_TOKEN не отменяет уже опубликованную утечку.
Как это реализовано в Authoriza SDK
SDK получает токены через Authorization Code Flow, сохраняет сессию и обновляет Access Token
при наличии Refresh Token. Для запроса Refresh Token используется scope offline_access.
Текущие сроки и claims описаны в статье о токенах Authoriza.
Чем Authoriza может быть полезна
Если вы ищете готовую реализацию обмена и обновления токенов для JavaScript или TypeScript, SDK Authoriza снимает часть рутинной работы. Перейдите к быстрому старту, когда определились с моделью хранения сессии.