В этой статье мы рассмотрим историю возникновения OAuth, его основные принципы работы и архитектуру. Поговорим о том, как протокол стал основой для безопасного взаимодействия между приложениями, не требующего передачи учётных данных. Кроме того, разберём ключевые различия между OAuth 2.0 и OpenID Connect (OIDC), чтобы понять, как OIDC дополняет возможности OAuth для обеспечения единой аутентификации (Single Sign-On, SSO). Мы также обсудим, какие сценарии применения лучше подходят для каждого из этих протоколов, и как обеспечить их безопасное использование в современных веб-приложениях.
История возникновения OAuth
Сегодня авторизация через социальные сети – привычное дело: нажимаешь кнопку соцсети, и мгновенно входишь на новый сайт, который получает доступ к вашему имени, фотографии и другим данным. Однако так было не всегда.
В «ранние времена» интернета всё было намного проще и одновременно менее безопасно. Пользователи просто передавали логин и пароль от одного сервиса другому, чтобы тот мог войти в их учётную запись и получить доступ к необходимой информации. Например, на заре становления, Facebook предлагал пользователям ввести логин и пароль от их аккаунта Gmail, чтобы отправить приглашения их контактам. Такой подход имел серьёзный недостаток: передавая свои данные, пользователи предоставляли сервису полный доступ к своей учётной записи.
Для решения этой проблемы и был разработан стандарт OAuth. С его помощью вы можете разрешить приложению доступ к вашим данным или функциям другого приложения от вашего имени, не раскрывая свой пароль. OAuth 2.0 делает этот процесс удобным и безопасным, предоставляя следующие ключевые преимущества:
- Повышенная безопасность. OAuth 2.0 позволяет предоставлять доступ к данным без необходимости передачи пароля, что защищает учётные данные пользователя от компрометации.
- Ограничение прав доступа. OAuth предоставляет доступ только к необходимым данным и функциям. Например, приложение может получить доступ к контактам, но не к личным сообщениям или файлам пользователя.
- Гибкость. OAuth 2.0 поддерживает различные типы разрешений, что позволяет адаптировать его под разные приложения (веб, мобильные и серверные) и сценарии доступа.
- Централизованное управление доступом. OAuth 2.0 даёт владельцу ресурса возможность управлять списком приложений, которым предоставлен доступ, и отзывать доступ в любой момент.
- Поддержка единого входа (SSO). OAuth 2.0 легко интегрируется с решениями SSO, такими как OpenID Connect, что позволяет пользователям использовать один аккаунт для доступа ко многим сервисам, упрощая процесс входа.
Основы Oauth 2.0
OAuth 2.0 основан на использовании базовых веб-технологий: HTTP-запросов, редиректов и т. п. Это делает его универсальным стандартом, который можно использовать на любой платформе с доступом к интернету и браузеру: на сайтах, в мобильных и десктопных приложениях, а также в браузерных плагинах.
Основные роли
Прежде чем рассмотреть сам процесс авторизации, важно понять основные роли, участвующие в схеме работы OAuth 2.0. Каждая из этих ролей выполняет свою задачу, обеспечивая безопасность и точность процесса доступа к данным.
Разделение на роли позволяет системе авторизации гибко контролировать доступ к защищённым ресурсам, минимизируя риски утечки информации. Рассмотрим эти роли на примере авторизации Facebook через Gmail:
- Владелец ресурса. Это пользователь, который владеет данными (такими как контакты в Gmail). Именно он решает, кому и в каком объёме предоставить доступ к своим данным. В некоторых случаях владельцем ресурса может быть не пользователь, а другой сервер, например, при взаимодействии серверов между собой.
- Клиент. Это устройство пользователя или сервис, которому требуется доступ к данным владельца ресурса. В нашем примере Facebook выступает клиентом, запрашивая доступ к контактам пользователя в Gmail для отправки приглашений.
- Сервер ресурсов. Это сервер, где хранятся защищённые данные владельца ресурса. В данном примере сервером ресурсов является сервер Gmail, на котором лежат контакты пользователя.
- Авторизационный сервер. Этот сервер отвечает за проверку прав доступа к данным. В нашем примере, авторизационный сервер – это сервер Google, который выполняет аутентификацию пользователя и выдаёт токен доступа (access token), подтверждающий разрешение на доступ к данным.
Базовая схема протокола
Теперь, когда роли понятны, вернёмся к примеру с Facebook и Gmail. На анимации ниже схематично показано, как правильно реализовать этот процесс с помощью OAuth 2.0. Google использует свой авторизационный сервер для проверки прав доступа на всех своих сервисах, включая Gmail, который в данном случае лишь хранит ресурсы, но не участвует в процессе авторизации.
Access Token
Ключевая цель процесса – предоставить клиенту (в нашем случае Facebook) доступ к данным, не раскрывая пароля. Клиент должен получить от авторизационного сервера специальный токен доступа (access token). Этот токен позволяет запрашивать данные у сервера ресурсов, но ограничивает доступ в соответствии с заданными разрешениями.
Особенности Access Token:
- Ограниченное время жизни. Access token имеет ограниченный срок действия для повышения безопасности.
- Возможность отзыва. Если есть подозрение, что токен скомпрометирован, его можно отозвать, заблокировав дальнейший доступ.
- Отдельность от пароля. Компрометация токена не означает утечку пароля, так как из токена невозможно получить логин и пароль пользователя.
- Ограниченные права доступа (scope). Access token может предоставить доступ только к определённым данным. Например, Facebook может запросить доступ только к списку контактов, но не к сообщениям.

Refresh Token
Помимо access token, авторизационный сервер может выдать клиенту refresh token. Когда срок действия access token истекает, клиент отправляет запрос к авторизационному серверу, передавая refresh token. Авторизационный сервер проверяет его действительность и, если всё в порядке, выдаёт новый access token. Так сессия пользователя остаётся активной без повторной аутентификации.
Поскольку refresh token даёт возможность запрашивать новые access token, его компрометация — серьёзная угроза. При утечке злоумышленник получает долгосрочный доступ к данным. Поэтому refresh token хранят в защищённой среде, особенно в серверных приложениях.
Для публичных клиентов (SPA, мобильные приложения) RFC 9700 требует дополнительной защиты: либо привязки токена к отправителю (sender-constrained), либо ротации refresh token. При ротации сервер при каждом обращении выдаёт новый refresh token и инвалидирует старый. Если старый токен предъявлен повторно — это сигнал компрометации: сервер должен отозвать всю цепочку токенов для данной сессии. Альтернативы sender-constrained — DPoP (RFC 9449) и mTLS: они криптографически привязывают токен к конкретному клиентскому ключу, и украденный токен без соответствующего приватного ключа становится бесполезным.
Способы получения Access Token
Существует четыре основных способа получения access token в OAuth 2.0, каждый из которых подходит для определённых сценариев:
- Authorization Code Grant. Это самый безопасный и надёжный метод. Он предполагает обмен одноразового кода авторизации на access token через серверную часть приложения, что делает его менее уязвимым к перехвату токена.
- Implicit Grant. Более простой метод, используемый для клиентских приложений без серверной части, таких как SPA (Single Page Applications). access token передаётся напрямую через URL-фрагмент, что упрощает реализацию, но снижает безопасность, так как токен может быть доступен через JavaScript.
- Resource Owner Password Credentials. В этом методе пользователь передаёт свои логин и пароль напрямую клиенту, который затем запрашивает access token у сервера авторизации. Он подходит только для доверенных клиентов, так как пользователь делится своими учётными данными с клиентом, что создаёт риск утечки.
- Client Credentials. Используется для межсерверного взаимодействия, когда одно серверное приложение (клиент) запрашивает access token у авторизационного сервера с использованием client_id и client_secret. Этот метод подходит для сценариев, когда доступ к ресурсам необходим от имени самого клиента, а не пользователя.
Подробно рассмотрим каждый способ.
Client Credentials
Рассмотрим один из самых простых способов авторизации в OAuth 2.0 — схему Client Credentials. Этот метод разработан для безопасного взаимодействия между сервисами и часто используется, когда один сервис должен обращаться к другому сервису без участия пользователя.

Каждый клиент должен быть зарегистрирован на авторизационном сервере. В процессе регистрации клиент получает уникальные идентификаторы:
- client_id – это публичный идентификатор клиента, который передаётся в каждом запросе на авторизацию. Он позволяет авторизационному серверу определить, какое приложение запрашивает доступ.
- client_secret – это секретный ключ, который используется для проверки подлинности клиента. Он должен храниться в надёжном месте и не должен быть раскрыт третьим лицам.
Запрос токена (1). Service 1 отправляет запрос к авторизационному серверу, передавая свои client_id и client_secret. Это делается с использованием метода POST и указанием типа авторизации grant_type=client_credentials:
curl --request POST \
--url 'https://YOUR_DOMAIN/oauth/token' \
--header 'content-type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id=YOUR_CLIENT_ID \
--data client_secret=YOUR_CLIENT_SECRET \
--data audience=YOUR_API_IDENTIFIER
Здесь audience указывает целевой ресурс (Service 2), для которого будет действовать access_token. Это поле определяет, какие именно ресурсы будут доступны по этому токену. Авторизационный сервер проверяет audience при выдаче токена, чтобы убедиться, что запрос направлен на доступ к конкретному API. Это помогает избежать использования токена не по назначению и усиливает безопасность.
Получение access_token (2). В ответ на запрос авторизационный сервер выдаёт access_token, который Service 1 может использовать для обращения к Service 2:
{
"access_token": "eyJz93a...k4laUWw",
"token_type": "Bearer",
"expires_in": 86400
}
access_token: строка токена, которая используется для авторизации запросов к Service 2. Это временный токен доступа.token_type: обычноBearer, что указывает на способ передачи токена в заголовкеAuthorization.expires_in: время действия токена в секундах (например, 86400 секунд, что соответствует 24 часам). После этого срока действия токен становится недействительным.
Обращение к Service 2 (3). Service 1 использует полученный access_token для отправки запросов к Service 2. Токен передаётся в заголовке Authorization с типом Bearer:
curl --request GET \
--url https://api2.com/api \
--header 'authorization: Bearer ACCESS_TOKEN' \
--header 'content-type: application/json'
Проверка токена (4). Получив запрос с access_token, Service 2 должен убедиться, что токен действителен и не был отозван. Для этого существуют два подхода:
- Запрос к авторизационному серверу: Service 2 может обратиться к авторизационному серверу с помощью протокола, описанного в RFC 7662, чтобы проверить действительность токена. Авторизационный сервер может подтвердить, что токен не истёк и не был отозван.
- Локальная проверка с использованием JWT: Если
access_tokenпредставлен в виде JWT (JSON Web Token), Service 2 может выполнить локальную проверку токена. JWT содержит в себе закодированную информацию о клиенте и правах доступа, и Service 2 может проверить подпись токена, чтобы убедиться в его подлинности без обращения к авторизационному серверу. Это снижает нагрузку на сервер и ускоряет обработку запросов.

Когда использовать Client Credentials?
Схема Client Credentials подходит для следующих сценариев:
- Межсерверное взаимодействие, где один сервер должен получить доступ к API другого сервера, например, для синхронизации данных.
- Микросервисная архитектура, где отдельные микросервисы взаимодействуют друг с другом через API.
- Сервисные учётные записи, когда доступ к API требуется не от имени конкретного пользователя, а от имени самого сервиса.
Важно учитывать, что client_secret должен храниться только в безопасных серверных окружениях. Это значит, что клиент должен быть доверительным и иметь возможность безопасно хранить client_secret без риска его утечки. Поэтому Client Credentials не рекомендуется использовать в клиентских приложениях, таких как мобильные или SPA, где client_secret может быть легко извлечён.
Resource Owner Password Credentials
Тем не менее схема встречается в legacy-системах, поэтому разберём, как она устроена — чтобы понимать, что именно перед нами, когда видим её в чужом коде.
Принцип прост до опасности: пользователь передаёт логин и пароль напрямую клиентскому приложению, клиент отправляет их на авторизационный сервер и получает токен. Авторизационный сервер здесь лишь посредник, но пользователь вынужден доверять клиенту свои учётные данные.
Запрос токена выглядит так:
curl -X POST https://auth.example.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "username=user@example.com" \
-d "password=secret" \
-d "client_id=my-app" \
-d "scope=read"Сервер возвращает стандартный ответ:
{
"access_token": "eyJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "8xLOxBtZp8"
}Проблема не в реализации, а в модели угроз. Клиент получает пароль — а значит, может его сохранить, передать куда угодно или скомпрометировать при утечке. Схема структурно несовместима с любым вторым фактором: нет редиректа, нет интерактивного шага, нет точки входа для MFA. Именно поэтому RFC 9700 не рекомендует, а запрещает этот грант.
Authorization Code Grant
Authorization Code Grant — рекомендуемый способ авторизации в OAuth 2.0, особенно для серверных приложений. Ключевое свойство: access token никогда не проходит через браузер. Пользователь получает только короткоживущий code, а обмен на токены происходит напрямую между сервером приложения и авторизационным сервером.
Flow разворачивается в пять шагов:
- Клиент перенаправляет пользователя на авторизационный сервер с параметрами
response_type=code,client_id,redirect_uri,scopeиstate. - Пользователь проходит аутентификацию и даёт согласие.
- Авторизационный сервер перенаправляет обратно на
redirect_uriс параметрамиcodeиstate. - Клиент проверяет
stateи обмениваетcodeна токены — server-to-server запросом сclient_secret. - Авторизационный сервер возвращает
access_tokenи, опционально,refresh_token.
Параметр state — одноразовый CSRF-токен. Клиент генерирует случайное значение перед редиректом, сохраняет в сессии и при получении callback проверяет совпадение. Несовпадение означает, что callback пришёл не в ответ на наш запрос — возможна CSRF-атака или подмена редиректа.
Запрос авторизации:
GET https://auth.example.com/oauth/authorize
?response_type=code
&client_id=my-app
&redirect_uri=https://app.example.com/callback
&scope=read%20write
&state=xK92mP1qZ7После согласия пользователя браузер редиректит на:
https://app.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=xK92mP1qZ7Клиент сверяет state, затем обменивает code:
curl -X POST https://auth.example.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=SplxlOBeZQQYbYS6WxSbIA" \
-d "redirect_uri=https://app.example.com/callback" \
-d "client_id=my-app" \
-d "client_secret=s3cr3t"В ответ приходят токены:
{
"access_token": "eyJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "8xLOxBtZp8"
}PKCE — Proof Key for Code Exchange
Authorization Code Grant с client_secret хорош для серверных приложений — они могут хранить секрет в безопасной среде. Мобильные приложения и SPA так не могут: любой секрет, зашитый в клиентский код, считается скомпрометированным по определению. Для них существует PKCE (RFC 7636). Согласно RFC 9700, PKCE обязателен для публичных клиентов и рекомендован для конфиденциальных.
Вместо статического client_secret клиент генерирует одноразовую пару значений:
code_verifier— случайная строка из символов[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"длиной 43–128 символовcode_challenge = BASE64URL(SHA256(code_verifier))с методомS256
В authorization request добавляются code_challenge и code_challenge_method=S256. В token request вместо секрета передаётся code_verifier. Сервер вычисляет хэш от полученного верификатора и сравнивает с code_challenge, который он сохранил при выдаче code.
Пример пары значений из RFC 7636:
code_verifier: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
code_challenge: E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cMЗапрос авторизации с PKCE:
GET https://auth.example.com/oauth/authorize
?response_type=code
&client_id=my-spa
&redirect_uri=https://app.example.com/callback
&scope=read
&state=xK92mP1qZ7
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256Обмен кода на токен — без client_secret, но с code_verifier:
curl -X POST https://auth.example.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=SplxlOBeZQQYbYS6WxSbIA" \
-d "redirect_uri=https://app.example.com/callback" \
-d "client_id=my-spa" \
-d "code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"code_verifier хранится в памяти JS-приложения на время flow — он одноразовый и живёт до завершения обмена. Перехват code без знания code_verifier бесполезен: без него токен не получить.
Implicit Grant
Implicit Grant появился как упрощение для браузерных приложений: вместо двухшагового flow авторизационный сервер возвращал access_token прямо в URL-фрагменте (#access_token=...), JavaScript читал его из window.location.hash без каких-либо серверных вызовов.
URL-фрагмент — принципиально небезопасное место для токена. Он оседает в истории браузера, попадает в Referer-заголовки при переходе на внешние ресурсы и в логи прокси-серверов. XSS-уязвимость на любой странице домена даёт атакующему прямой доступ к токену. При этом нет механизма подтверждения получателя: client_secret у публичного клиента нет, и сервер не может убедиться, что токен получил именно ожидаемый клиент, а не перехватчик с подменённым redirect_uri.
Authorization Code + PKCE устраняет все эти проблемы без серверной инфраструктуры. code_verifier живёт в памяти приложения, client_secret не нужен, токен никогда не появляется в URL. Для любого публичного клиента это единственный путь, соответствующий актуальным требованиям безопасности.
Device Authorization Grant
Представьте телевизор, которому нужно войти в аккаунт Netflix. Нет браузера, нет нормальной клавиатуры — только пульт. Именно для таких устройств появился Device Authorization Grant, описанный в RFC 8628.
Грант решает одну конкретную задачу: аутентифицировать устройство с ограниченным вводом или вообще без браузера. Сюда попадают Smart TV, IoT-устройства, игровые консоли и CLI-утилиты — например, GitHub CLI (gh auth login) и Google Cloud SDK (gcloud auth login).
Flow делится на две независимые ветки: устройство общается с сервером по polling, а пользователь параллельно подтверждает доступ со своего телефона или ноутбука.
Шаг 1. Устройство запрашивает код авторизации:
curl -X POST https://YOUR_DOMAIN/oauth/device/code \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=YOUR_CLIENT_ID&scope=openid%20profile'Сервер отвечает сразу несколькими значениями:
{
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
"user_code": "WDJB-MJHT",
"verification_uri": "https://YOUR_DOMAIN/activate",
"verification_uri_complete": "https://YOUR_DOMAIN/activate?user_code=WDJB-MJHT",
"expires_in": 900,
"interval": 5
}user_code — короткий код, который устройство показывает на экране. RFC 8628 не фиксирует его длину: сервер выбирает её сам, балансируя между удобством ввода и энтропией. verification_uri_complete содержит уже вписанный код — удобно для QR-кодов на Smart TV, чтобы пользователь не вводил символы вручную.
Пользователь открывает verification_uri на своём устройстве, вводит user_code и подтверждает запрос. Устройство в это время ничего не знает о том, что происходит на стороне пользователя, и просто поллит token endpoint с заданным интервалом:
curl -X POST https://YOUR_DOMAIN/oauth/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=urn:ietf:params:oauth:grant-type:device_code
&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS
&client_id=YOUR_CLIENT_ID'Пока пользователь не подтвердил запрос, сервер возвращает одно из четырёх состояний:
authorization_pending— пользователь ещё не ответил, продолжать polling;slow_down— устройство опрашивает слишком часто, нужно увеличить интервал на 5 секунд;access_denied— пользователь явно отклонил запрос;expired_token—device_codeистёк, нужно начинать flow заново.
Как только пользователь подтверждает доступ, следующий polling-запрос возвращает полноценный access_token.
Грант подходит только тогда, когда на устройстве действительно нет возможности открыть браузер. Если браузер есть — используйте Authorization Code + PKCE: он не требует polling и не держит device_code живым несколько минут.
OpenID Connect
OAuth 2.0 решает задачу авторизации — приложение получает доступ к ресурсам от имени пользователя. Но сам протокол не отвечает на вопрос «кто этот пользователь?». Это принципиальное разграничение: авторизация говорит «ты можешь», аутентификация говорит «ты — это ты».
OpenID Connect (OIDC) — надстройка над OAuth 2.0, которая добавляет уровень аутентификации. Технически это тот же Authorization Code Flow, но с дополнительным токеном — id_token. На основе OIDC строятся системы единого входа (SSO).
Различие между двумя токенами критично:
id_token— JWT с данными о пользователе. Его назначение — подтвердить личность: клиентское приложение читает токен, проверяет подпись и узнаёт, кто вошёл. Этот токен предназначен только для клиента, не для API.access_token— токен для доступа к защищённым ресурсам. Его передают в заголовкеAuthorizationпри вызовах API.
Распространённая ошибка — передавать id_token в API-запросах вместо access_token. Сервер ресурсов не должен принимать id_token: он не предназначен для этой роли и не несёт нужной аудитории (aud).

JWT (JSON Web Token) — подписанный JSON-объект в формате header.payload.signature, закодированный в Base64URL. Подпись позволяет получателю проверить токен без обращения к серверу.
Поток OpenID Connect
Поток OIDC строится поверх Authorization Code Flow. Отличие начинается с первого запроса: клиент добавляет scope=openid. Именно это значение сигнализирует серверу авторизации, что нужен id_token. Без openid в scope id_token не возвращается.
В ответе на обмен кода токены приходят вместе:
{
"access_token": "eyJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiJ9...",
"refresh_token": "8xLOxBtZp8"
}id_token — это JWT. После декодирования payload выглядит так:
{
"iss": "https://accounts.google.com",
"sub": "110169484474386276334",
"aud": "s6BhdRkqt3",
"exp": 1311281970,
"iat": 1311280970,
"name": "Jane Doe",
"email": "jane@example.com"
}Первые пять claims — обязательные по спецификации. iss + sub вместе образуют глобально уникальный идентификатор пользователя. aud должен совпадать с client_id приложения — это защита от того, чтобы токен, выданный одному клиенту, не приняло другое приложение. В Implicit Flow к обязательным добавляется nonce — одноразовое значение для защиты от replay-атак.
Клиент проверяет подпись id_token самостоятельно, используя публичный ключ провайдера. Это устраняет необходимость дополнительного сетевого запроса для валидации.
Scopes и claims
OIDC стандартизирует набор scope-значений, каждое из которых открывает определённую группу claims:
| Scope | Добавляемые claims |
|---|---|
openid | Обязательный. Только sub |
profile | name, given_name, family_name, picture, locale |
email | email, email_verified |
address | address (структурированный объект) |
phone | phone_number, phone_number_verified |
Если нужны только базовые данные для SSO — достаточно openid. Полный профиль можно запросить через UserInfo Endpoint (GET /userinfo с access_token), не перегружая id_token.
Discovery Endpoint
OIDC-провайдеры публикуют метаданные по стандартному адресу:
GET {issuer}/.well-known/openid-configurationНапример: https://accounts.google.com/.well-known/openid-configuration
Ответ — JSON с полным описанием возможностей провайдера. Ключевые поля:
issuer— базовый URL провайдераauthorization_endpoint— адрес для старта авторизацииtoken_endpoint— где обменивают код на токеныuserinfo_endpoint— endpoint для получения данных пользователяjwks_uri— публичные ключи для проверки подписи токеновscopes_supported— список поддерживаемых scope
Клиентские библиотеки используют Discovery для автоконфигурации: достаточно указать issuer, остальное они находят сами.
Заключение
OAuth 2.0 и OpenID Connect решают разные задачи, но работают как единая система: OAuth 2.0 управляет доступом к ресурсам, OIDC поверх него добавляет подтверждение личности. Вместе они покрывают большинство сценариев — от делегированного API-доступа до SSO в корпоративных системах. Главное не путать роли токенов: access_token идёт в API, id_token остаётся у клиента.
Стандарт продолжает развиваться. OAuth 2.1 (пока в статусе draft) консолидирует накопленный опыт безопасности: убирает deprecated grants (implicit, resource owner password), делает PKCE обязательным для всех публичных клиентов и ужесточает требования к redirect URI. DPoP (RFC 9449) привязывает токен к криптографическому ключу клиента, что лишает смысла кражу bearer-токена. PAR (RFC 9126) передаёт параметры авторизационного запроса через back-channel ещё до редиректа пользователя, закрывая класс атак на front-channel.
