Skip to content

Направление: CLI / устройства без браузера

Device Authorization Grant (RFC 8628) — для приложений, у которых нет удобного способа принять редирект браузера: CLI-инструменты, smart TV, IoT. Пользователь подтверждает вход на отдельном устройстве, где браузер есть.

Предполагается, что клиент уже создан (02-client.md).


Шаг 1 — запрос device-авторизации

bash
curl -X POST http://localhost:3002/device_authorization \
  -d "client_id=<client_id>" \
  -d "client_secret=<client_secret>" \
  -d "scope=openid profile email"
json
{
  "device_code": "<opaque, для опроса /token>",
  "user_code": "WDJB-MJHT",
  "verification_uri": "http://localhost:3002/device",
  "verification_uri_complete": "http://localhost:3002/device?user_code=WDJB-MJHT",
  "expires_in": 900,
  "interval": 5
}

Шаг 2 — показать код пользователю

Выведите в терминале verification_uri_complete (кликабельная ссылка, код уже подставлен) либо verification_uri вместе с user_code отдельно, если приложение не может открыть ссылку само:

Перейдите по ссылке и подтвердите вход:
  http://localhost:3002/device?user_code=WDJB-MJHT

Или откройте http://localhost:3002/device и введите код: WDJB-MJHT

Пользователь логинится (если ещё не залогинен) и подтверждает или отклоняет запрос на этой странице. Если у клиента задана организация — политики входа применяются здесь так же, как и при обычном логине.

Шаг 3 — опрос /token

Начинайте опрос не чаще, чем раз в interval секунд из ответа Шага 1.

bash
curl -X POST http://localhost:3002/token \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
  -d "device_code=<device_code>" \
  -d "client_id=<client_id>" \
  -d "client_secret=<client_secret>"
Ответ (400)Что делать
authorization_pendingПользователь ещё не подтвердил — продолжайте опрос с тем же интервалом
slow_downОпрос идёт чаще, чем interval — увеличьте интервал и продолжайте
expired_tokendevice_code истёк (по умолчанию 15 минут) — начните заново с Шага 1
access_deniedПользователь отклонил запрос — прекратите опрос, сообщите пользователю

Успех (200): тот же формат ответа, что у Authorization Code Flow — access_token, id_token (если запрошен scope openid), refresh_token (если запрошен offline_access). Обновление токена и логика refresh_token — как в 03-web-app.md, grant type тот же (grant_type=refresh_token).


Особенности для CLI

  • Храните refresh_token в системном хранилище секретов ОС (Keychain / Credential Manager / Secret Service), а не в открытом файле конфигурации.
  • Back-channel/front-channel logout (см. 03-web-app.md) не применимы к CLI напрямую — у CLI нет постоянно слушающего HTTP-эндпоинта и нет браузера для iframe. Реагируйте на недействительный refresh_token (invalid_grant при обновлении) как на сигнал разлогина — удалите локально сохранённый токен и попросите пользователя войти заново.
  • /revoke можно вызвать явно при команде logout в самом CLI — подробнее в 06-operations.md.