Вход через UNIT ID
UNIT ID поддерживает один поток — Authorization Code с PKCE (S256). Он подходит и для серверных приложений, и для приложений в браузере и на телефоне.
/oauth/authorize → получить code на свой адрес возврата → обменять код на токены в /oauth/token → узнать человека из id_token или /oauth/userinfo.Шаг 1. Запрос авторизации
| Параметр | Что это | |
|---|---|---|
client_id | обязательно | Идентификатор приложения, unit-…. |
response_type | обязательно | Только code. |
redirect_uri | обязательно | Один из зарегистрированных адресов возврата — точное совпадение, включая слэш в конце. |
scope | Права через пробел, например openid profile email. openid добавляется всегда. Права, которые приложению не выданы при регистрации, молча отбрасываются. | |
state | рекомендуется | Случайная строка: вернётся без изменений, сверьте её — это защита от подделки запроса. |
code_challenge | для публичных — обязательно | BASE64URL(SHA256(code_verifier)) без знаков = в конце. |
code_challenge_method | Только S256. | |
nonce | Случайная строка: вернётся в id_token, сверьте её. До 200 символов. | |
prompt | consent — показать экран согласия, даже если человек уже разрешал. |
code_verifier — случайная строка из 43–128 символов (буквы, цифры, -._~). Сохраните её в сессии до возврата: она понадобится на шаге 3. PKCE стоит использовать и серверным приложениям с секретом.
# Python: verifier и challenge
import base64, hashlib, secrets
verifier = secrets.token_urlsafe(48)
challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).rstrip(b"=").decode()
Шаг 2. Человек входит и соглашается
Если человек не вошёл в UNIT ID, он увидит страницу входа: пароль, вход с телефона или код 2FA — это решает UNIT ID, приложению делать ничего не нужно. Затем — экран согласия со списком прав. Повторно он не показывается, пока приложение не попросит новые права. Сервисы UNIT, отмеченные администратором как свои, входят без экрана согласия.
После согласия UNIT ID перенаправит на адрес возврата:
https://myapp.ru/auth/callback?code=Gx3…&state=СЛУЧАЙНАЯ_СТРОКА
Если человек отказался:
https://myapp.ru/auth/callback?error=access_denied&state=СЛУЧАЙНАЯ_СТРОКА
Ошибки в самом запросе (неизвестный client_id, чужой адрес возврата) показываются человеку на странице UNIT ID — на непроверенный адрес UNIT ID не перенаправляет.
Шаг 3. Обмен кода на токены
Запрос с вашего сервера, тело — application/x-www-form-urlencoded. Приложение с секретом передаёт его заголовком Authorization: Basic base64(client_id:client_secret) или полями client_id и client_secret. Публичное — только client_id.
| Поле | Значение |
|---|---|
grant_type | authorization_code |
code | Код из шага 2. Живёт 60 секунд и срабатывает один раз. |
redirect_uri | Тот же адрес, что в шаге 1. |
code_verifier | Строка, из которой считали code_challenge. |
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "Qm9i…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile email offline_access",
"refresh_token": "dGhp…", // только с правом offline_access
"id_token": "eyJhbGciOiJSUzI1NiIs…" // только с правом openid
}
Шаг 4. Кто вошёл
Два способа — выбирайте любой:
- id_token — подписанный JWT прямо в ответе. Проверьте подпись и поля — см. «Токены и id_token».
- userinfo — запрос с
access_token; всегда актуальные данные.
curl https://auth.labunit.ru/oauth/userinfo -H "Authorization: Bearer ACCESS_TOKEN"
Набор полей зависит от выданных прав — см. «Права и данные».
Обновление токена
С правом offline_access вместе с токеном доступа приходит refresh_token (живёт 30 дней). Когда access_token истёк (через час), получите новый:
curl -X POST https://auth.labunit.ru/oauth/token \
-u "CLIENT_ID:CLIENT_SECRET" \
-d grant_type=refresh_token \
-d refresh_token=REFRESH_TOKEN
Токен обновления одноразовый: в ответе придёт новый, старый перестаёт действовать. Сохраняйте новый каждый раз. Если человек отозвал доступ, сменил аккаунт или аккаунт отключили — придёт invalid_grant: отправьте человека войти заново.
Отзыв токена
curl -X POST https://auth.labunit.ru/oauth/revoke -d token=ACCESS_ИЛИ_REFRESH_TOKEN
Вызывайте при выходе из приложения. Ответ всегда 200 с {}.
Выход
Чтобы человек вышел и из UNIT ID (иначе следующий «Войти» пустит без пароля), после своего выхода перенаправьте его на:
https://auth.labunit.ru/logout?next=https://myapp.ru/
next принимается, только если его домен совпадает с доменом одного из ваших адресов возврата; иначе человек попадёт на страницу входа UNIT ID.
Публичные приложения
SPA, мобильные и настольные приложения не могут хранить секрет — регистрируйте их как «Публичные». Для них code_challenge обязателен, а в /oauth/token передаётся только client_id. Токены храните в памяти или защищённом хранилище платформы, не в localStorage.