# OAuth 2.0 и OpenID Connect

> OAuth 2.0 — протокол делегирования доступа к API через токены; OpenID Connect — надстройка над ним для входа пользователей («войти через…»).

Источник: https://llmdocs.ru/wiki/oauth-oidc/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **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 или близких к нему схемах. Разница между проверкой личности и проверкой прав разобрана в статье [Аутентификация и авторизация](https://llmdocs.ru/wiki/authn-authz.md).

## История

До OAuth сторонние сервисы просили у пользователя логин и пароль от почты, чтобы, например, импортировать контакты, — это давало им полный доступ к аккаунту. OAuth 1.0 (2007, RFC 5849) решил задачу, но требовал сложной криптографической подписи каждого запроса. OAuth 2.0 (2012) упростил протокол, переложив защиту канала на [TLS](https://llmdocs.ru/wiki/tls.md), и стал «рамкой» с несколькими сценариями (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]

1. Клиент генерирует случайный `code_verifier` и его хеш `code_challenge` (PKCE).[2]
2. Браузер пользователя перенаправляется на сервер авторизации с параметрами `client_id`, `redirect_uri`, `scope` (запрашиваемые права), `state` (защита от [CSRF](https://llmdocs.ru/wiki/csrf.md)) и `code_challenge`.
3. Пользователь входит и соглашается выдать права.
4. Сервер перенаправляет браузер обратно на `redirect_uri` с одноразовым **кодом авторизации**.
5. Клиент обменивает код на токены прямым запросом к серверу, прикладывая `code_verifier`. Перехваченный код без него бесполезен.

```http
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](https://llmdocs.ru/wiki/json.md) с `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](https://llmdocs.ru/wiki/cookies-sessions.md).

В России для публичных сервисов действуют требования об авторизации пользователей через российские сервисы (Яндекс ID, VK ID, Госуслуги, номер телефона) — они тоже реализуют OAuth 2.0 и, в разной степени, OIDC.

## См. также

- [Аутентификация и авторизация](https://llmdocs.ru/wiki/authn-authz.md)
- [Cookie и сессии](https://llmdocs.ru/wiki/cookies-sessions.md)
- [Двухфакторная аутентификация](https://llmdocs.ru/wiki/two-factor-auth.md)
- [CSRF](https://llmdocs.ru/wiki/csrf.md)
- [TLS](https://llmdocs.ru/wiki/tls.md)

## Источники

1. [RFC 6749 — The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749)
2. [RFC 7636 — Proof Key for Code Exchange (PKCE)](https://www.rfc-editor.org/rfc/rfc7636)
3. [RFC 9700 — Best Current Practice for OAuth 2.0 Security](https://www.rfc-editor.org/rfc/rfc9700)
4. [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)
5. [The OAuth 2.1 Authorization Framework (draft)](https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/)
6. [RFC 7519 — JSON Web Token (JWT)](https://www.rfc-editor.org/rfc/rfc7519)
7. [RFC 8628 — OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628)
