Как реализована аутентификация с поддержкой OpenID и OAuth 2.0
Что проверяют
Понимаете ли вы, чем OpenID Connect отличается от OAuth 2.0 и какие правила действуют для мобильного клиента. Главный маркер: знаете ли вы про PKCE и почему в приложении нельзя хранить client secret. Следом спрашивают, где лежат токены и как они обновляются.
Как отвечать
- термины: OAuth 2.0 выдаёт приложению доступ к API через
access_token. OpenID Connect добавляет аутентификацию:id_tokenв формате JWT с данными о пользователе и эндпоинтuserinfo. Старый OpenID 2.0 давно не используют, говорить стоит про OIDC; - поток: Authorization Code с PKCE. Приложение генерирует
code_verifier, отправляет его хешcode_challenge(методS256), получает код на redirect URI и меняет его на токены, предъявляя исходный verifier. Перехваченный код без него бесполезен; - публичный клиент: APK декомпилируется, поэтому client secret в приложение не кладут;
- браузер: вход идёт через Custom Tabs, а не через
WebView. Этого требует RFC 8252, и многие провайдеры блокируют вход во встроенном WebView; - библиотека: AppAuth for Android сама делает PKCE и
state, читает discovery-документ/.well-known/openid-configuration, аAuthState.performActionWithFreshTokensобновляет access-токен перед запросом; - redirect: надёжнее App Links на своём домене с
assetlinks.json, custom scheme проще перехватить другим приложением; - хранение: токены шифруются ключом из Android Keystore, а
Authenticatorв OkHttp ловит 401 и повторяет запрос с новым токеном.
Результат входа получают через Activity Result API (registerForActivityResult), startActivityForResult устарел.
Где спотыкаются
Используют implicit flow или кладут client secret в BuildConfig. Оба варианта небезопасны для мобильного клиента.
Проверяют id_token только в приложении и отправляют на бэкенд данные пользователя «как есть». Подпись, iss, aud и exp должен проверять сервер.
Не синхронизируют обновление: параллельные запросы одновременно получают 401 и тратят один refresh-токен, а при ротации refresh-токенов пользователя выбрасывает из аккаунта.