OAuth 2.0 и OpenID Connect
| OAuth 2.0 | RFC 6749 (октябрь 2012) |
|---|---|
| OpenID Connect | OpenID Connect Core 1.0 (OpenID Foundation, 2014) |
| Следующая версия | OAuth 2.1 (черновик IETF) |
| Токены | access token, refresh token, ID token (JWT) |
| Основной поток | Authorization Code + PKCE |
| Роли | владелец ресурса, клиент, сервер авторизации, сервер ресурсов |
| Реализации | Keycloak, Authentik, Ory Hydra, Auth0, Яндекс ID, VK ID |
OAuth 2.0 — открытый протокол делегирования доступа: он позволяет приложению получить ограниченный доступ к ресурсам пользователя в другом сервисе (почте, календарю, репозиториям), не узнавая его пароля. Вместо пароля приложение получает токен доступа с ограниченными правами и сроком жизни. OpenID Connect (OIDC) — слой поверх OAuth 2.0, который добавляет аутентификацию: подтверждённые сведения о том, кто именно вошёл. Кнопки «Войти через Яндекс», «Войти через GitHub» работают на OIDC или близких к нему схемах. Разница между проверкой личности и проверкой прав разобрана в статье Аутентификация и авторизация.
История
До OAuth сторонние сервисы просили у пользователя логин и пароль от почты, чтобы, например, импортировать контакты, — это давало им полный доступ к аккаунту. OAuth 1.0 (2007, RFC 5849) решил задачу, но требовал сложной криптографической подписи каждого запроса. OAuth 2.0 (2012) упростил протокол, переложив защиту канала на TLS, и стал «рамкой» с несколькими сценариями (grant types).[1] Поскольку OAuth сам по себе не говорит, кто пользователь, компании изобретали собственные надстройки, пока OpenID Foundation не выпустила в 2014 году OpenID Connect.[4]
Роли
| Роль | Пример |
|---|---|
| Владелец ресурса (resource owner) | пользователь |
| Клиент (client) | ваше веб-приложение или мобильная программа |
| Сервер авторизации (authorization server) | oauth.yandex.ru, Keycloak |
| Сервер ресурсов (resource server) | API, принимающее токены |
Клиент заранее регистрируется у сервера авторизации и получает client_id (и для серверных приложений — client_secret), а также указывает разрешённые адреса возврата (redirect URI).
Поток Authorization Code с PKCE
Основной и рекомендуемый для всех типов клиентов сценарий:[3]
- Клиент генерирует случайный
code_verifierи его хешcode_challenge(PKCE).[2] - Браузер пользователя перенаправляется на сервер авторизации с параметрами
client_id,redirect_uri,scope(запрашиваемые права),state(защита от CSRF) иcode_challenge. - Пользователь входит и соглашается выдать права.
- Сервер перенаправляет браузер обратно на
redirect_uriс одноразовым кодом авторизации. - Клиент обменивает код на токены прямым запросом к серверу, прикладывая
code_verifier. Перехваченный код без него бесполезен.
POST /token HTTP/1.1
Host: auth.example.ru
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQ&redirect_uri=https%3A%2F%2Fapp.example.ru%2Fcb
&client_id=app&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
В ответ приходит JSON с access_token, сроком жизни expires_in, при необходимости refresh_token, а в OIDC — ещё и id_token.
Другие сценарии: Client Credentials — сервис обращается к API от своего имени, без пользователя; Device Authorization — вход на телевизоре или в консольной утилите по коду, введённому на телефоне.[7] Устаревшие сценарии Implicit (токен прямо в URL) и Password (клиент собирает пароль) в OAuth 2.1 удалены.[5]
Токены
- Access token — предъявляется API в заголовке
Authorization: Bearer …. Может быть непрозрачной строкой (сервер проверяет её запросом introspection) или самодостаточным JWT с подписью. Живёт минуты или часы. - Refresh token — долгоживущий, позволяет получить новый access token без участия пользователя. Хранится только у клиента и должен быть защищён.
- ID token (OIDC) — подписанный JWT[6] с полями
iss(кто выдал),sub(постоянный идентификатор пользователя),aud(для какого клиента),exp,nonceи, по запросу,email,name. Клиент обязан проверить подпись и эти поля.
OIDC добавляет также эндпоинт /userinfo, стандартные scope (openid, profile, email) и документ discovery по адресу /.well-known/openid-configuration, из которого библиотеки автоматически узнают адреса и ключи сервера.
Безопасность
Типичные ошибки — неточная проверка redirect_uri (позволяет украсть код), отсутствие state/PKCE, хранение токенов в localStorage при уязвимости к XSS, использование access token как доказательства входа без проверки aud. Сводные рекомендации собраны в RFC 9700.[3] Для браузерных приложений часто используют схему BFF (backend for frontend): токены держит сервер, а браузер получает обычную сессионную cookie.
В России для публичных сервисов действуют требования об авторизации пользователей через российские сервисы (Яндекс ID, VK ID, Госуслуги, номер телефона) — они тоже реализуют OAuth 2.0 и, в разной степени, OIDC.