Токены и id_token
Сколько живут токены, как устроен id_token и как его проверить.
Сроки жизни
| Что | Срок | Особенности |
|---|---|---|
| Код авторизации | 60 секунд | Одноразовый: повторный обмен — invalid_grant. |
access_token | 1 час | Непрозрачная строка — не разбирайте её, отправляйте как есть. |
refresh_token | 30 дней | Одноразовый: каждое обновление выдаёт новый. |
id_token | 1 час | Проверяется по ключам JWKS; для входа достаточно проверить один раз. |
Токен может перестать действовать раньше срока: человек отозвал доступ приложению или вышел на устройстве, где разрешал вход; сменил пароль или включил 2FA (это выход на остальных устройствах); администратор отключил аккаунт. Ответ 401 от API или invalid_grant при обновлении означает одно — попросите человека войти заново.
Что внутри id_token
id_token — JWT, подписанный RS256. Заголовок содержит kid — ключ, которым подписан токен.
{
"iss": "https://auth.labunit.ru",
"sub": "s-4kq9tz",
"aud": "unit-0123456789abcdef",
"iat": 1791800000,
"exp": 1791803600,
"nonce": "…", // если передавали в запросе
"name": "Анна Смирнова", // profile
"preferred_username": "anna",
"unit_roles": ["student"],
"unit_tags": ["школа", "ученик"],
"email": "anna@labunit.ru", // email
"email_verified": true
}
Проверка
- Возьмите ключ с совпадающим
kidизhttps://auth.labunit.ru/oauth/jwks. Ключи можно кешировать; еслиkidне нашёлся — перечитайте JWKS. - Проверьте подпись алгоритмом RS256. Другие алгоритмы (особенно
noneиHS256) не принимайте. issравенhttps://auth.labunit.ru,aud— вашемуclient_id.expв будущем (допуск на расхождение часов — минута-две).- Если передавали
nonce— он совпадает с сохранённым.
Python · PyJWT
import jwt # pip install pyjwt[crypto]
jwks = jwt.PyJWKClient("https://auth.labunit.ru/oauth/jwks")
key = jwks.get_signing_key_from_jwt(id_token).key
claims = jwt.decode(id_token, key, algorithms=["RS256"],
audience=CLIENT_ID, issuer="https://auth.labunit.ru", leeway=60)
user_id = claims["sub"]
Node.js · jose
import { createRemoteJWKSet, jwtVerify } from "jose";
const jwks = createRemoteJWKSet(new URL("https://auth.labunit.ru/oauth/jwks"));
const { payload } = await jwtVerify(idToken, jwks, {
issuer: "https://auth.labunit.ru", audience: CLIENT_ID, algorithms: ["RS256"],
});
Если вы получили id_token напрямую от /oauth/token по HTTPS со своего сервера, его можно считать подлинным и без проверки подписи. Проверка обязательна, когда токен попадает к вам через браузер или от другого сервиса.