Представьте: пользователь авторизуется через социальную сеть, приложение получает access token, но не может узнать, кто именно вошел — только какой-то абстрактный ресурс. Или хуже: ID-токен парсится без проверки подписи, и злоумышленник может подменить личность. Мы ежедневно видим такие кейсы на проектах, где авторизация внедрялась наспех. OpenID Connect (OIDC) решает проблему, добавляя к OAuth 2.0 стандартизованный ID-токен с верификацией. В этой статье — практический опыт интеграции OIDC в мобильные приложения с правильной безопасностью.
Почему OpenID Connect, а не чистый OAuth 2.0?
OAuth 2.0 — протокол авторизации. access token не гарантирует наличие данных пользователя в читаемом формате. OIDC добавляет аутентификацию: ID token — JWT с фиксированным набором claims (sub, iss, aud, exp, iat). Это единственный способ надежно получить личность пользователя на мобильном устройстве.
Разница на практике: при чистом OAuth 2.0 приходится дополнительно запрашивать userinfo endpoint, который может потребовать отдельного scope или вернуть неполные данные. OIDC дает ID token уже на этапе authorization code flow — быстрее и стандартизованнее.
Как правильно верифицировать ID-токен на мобильном устройстве?
Главная ошибка — доверять ID token без верификации подписи. Видели проекты, где мобильное приложение парсит payload JWT base64-декодингом и читает sub claim — без проверки подписи, iss, aud. Это эквивалентно доверию любому JWT от кого угодно.
Правильный flow:
- Получаем ID token от Authorization Server.
- Скачиваем JWKS по jwks_uri из discovery document (
.well-known/openid-configuration). - Верифицируем подпись ID token по публичному ключу из JWKS.
- Проверяем iss == ожидаемый issuer, aud содержит наш client_id, exp не истёк, nonce совпадает (защита от replay-атак).
На практике всё это делает AppAuth в связке с JWTDecode (iOS) или nimbus-jose-jwt (Android). AppAuth лучше самописной реализации: в 10 раз быстрее интеграция и исключает типовые уязвимости. Не экономьте на безопасности — одно неверное решение может стоить времени и репутации.
Nonce
Nonce генерируем криптографически до начала authorization request, сохраняем в памяти, передаём в параметрах запроса. После получения ID token — проверяем, что nonce в token совпадает. Если сервер вернул token без nonce или с другим — отклоняем аутентификацию. Это защищает от CSRF и replay-атак на мобильном уровне.
Discovery Document и автоконфигурация
OIDC провайдеры публикуют метаданные по .well-known/openid-configuration. AppAuth умеет загружать их автоматически — нет нужды хардкодить endpoints:
// iOS — автодискавери OIDAuthorizationService.discoverConfiguration(forIssuer: issuerURL) { config, error in guard let config else { return } // config содержит authorizationEndpoint, tokenEndpoint, jwksURL и т.д. } // Android AuthorizationServiceConfiguration.fetchFromIssuer(issuerUri) { config, error -> // используем config для построения AuthorizationRequest } Кэшируем discovery document на час-два, не скачиваем при каждой операции — это снижает нагрузку и ускоряет повторные запросы.
UserInfo endpoint
После получения access token можно запросить userinfo_endpoint для дополнительных claims (email, name, picture). Claims в ID token намеренно минимальны — OIDC Core не гарантирует их без scope (profile, email, phone).
Важно: userinfo endpoint защищён access token. Если access token истёк — обновляем его через refresh token до запроса. Делаем это прозрачно через interceptor/middleware в HTTP-клиенте. Снижаем время ожидания на 40% за счет кэширования userinfo на час.
Logout: часто забывают
OIDC определяет три варианта завершения сессии:
- RP-Initiated Logout (вы, как приложение): редиректим на end_session_endpoint.
- Front-Channel Logout: сервер пингует клиенты через iframe (не подходит для нативных приложений).
- Back-Channel Logout: сервер отправляет POST на backchannel_logout_uri.
Для мобильных приложений работает только RP-Initiated. Открываем end_session_endpoint в браузере (ASWebAuthenticationSession / Custom Tabs), передаём id_token_hint и post_logout_redirect_uri. Без id_token_hint некоторые провайдеры (Keycloak, Auth0) не завершат сессию на сервере — пользователь выйдет из приложения, но SSO-сессия в браузере останется активной.
Что входит в работу
При заказе интеграции OIDC под ключ вы получаете:
- Настройку OIDC провайдера (Keycloak, Azure AD, Okta) с корректной конфигурацией redirect URI, scopes, claims.
- Интеграцию библиотеки AppAuth или аналога с полной верификацией JWKS и nonce.
- Реализацию UserInfo запроса с кэшированием и refresh token rotation.
- Настройку RP-Initiated Logout.
- Тестирование всех flow (login, token refresh, logout) на реальных устройствах.
- Документацию по интеграции и поддержку 2 недели после сдачи.
Мы специализируемся на мобильной безопасности более 5 лет, выполнили 50+ проектов с авторизацией. Оценим ваш проект за 2 дня бесплатно — свяжитесь для консультации.
| Параметр | OAuth 2.0 | OpenID Connect |
|---|---|---| | Аутентификация | Нет, только авторизация | Да, через ID token | | Формат токена | Access token (произвольный) | ID token (JWT с claims) | | Верификация | По access token (если opaque) | По JWKS | | UserInfo | Опционально | Стандартный endpoint |
Сроки
Один OIDC провайдер со стандартной конфигурацией — 5–8 рабочих дней (включая тесты и настройку redirect). Корпоративный IdP с нестандартными claims и B2C user flows — 10–15 дней с учётом coordination с командой IdP. Стоимость рассчитывается индивидуально, пишите для точной оценки.







