В этом руководстве описывается, как реализовать функцию "Войти с аккаунтом Google". В нем рассматриваются следующие шаги:
- Добавьте зависимости в приложение.
- Создайте экземпляр
CredentialManager. - Создайте нижний экран.
- Создайте поток кнопки.
- Обработка ответа на вход.
- Обработка ошибок.
- Обработка выхода из аккаунта.
Добавьте зависимости в приложение
В файле build.gradle модуля объявите зависимости, используя последнюю версию Менеджера учетных данных, сервисов Google Play Auth и googleid:
Котлин
dependencies { implementation("androidx.credentials:credentials:1.7.0-alpha03") implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha03") implementation("com.google.android.libraries.identity.googleid:googleid:<latest version>") }
Круто
dependencies { implementation "androidx.credentials:credentials:1.7.0-alpha03" implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha03" implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>" }
Создайте экземпляр Менеджера учетных данных
Используйте контекст приложения или действия, чтобы создать объект CredentialManager.
// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)
Создание нижнего экрана
Нижний экран – это встроенный интерфейс Менеджера учетных данных. Использование этого интерфейса создает единообразный опыт для всех способов аутентификации, таких как пароли, ключи доступа и войти с аккаунтом Google.
Как настроить запрос на вход для ранее авторизованных аккаунтов
Попытайтесь выполнить запрос на вход в Google с помощью GetGoogleIdOption, чтобы получить токен идентификатора Google пользователя.
В приведенных ниже фрагментах кода проверяется, является ли аккаунт авторизованным.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(true)
.setServerClientId(WEB_CLIENT_ID)
.setAutoSelectEnabled(true)
.setNonce(generateSecureRandomNonce())
.build()
Объект запроса googleIdOption настраивается следующим образом:
Фильтрация ранее авторизованных аккаунтов. Чтобы получить авторизованные аккаунты, которые ранее использовались для входа в приложение, задайте для
setFilterByAuthorizedAccountsзначениеtrue.Обратите внимание, что значение по умолчанию для
setFilterByAuthorizedAccounts–true. Это означает, что режим работы по умолчанию для пользовательского интерфейса нижнего экрана – показывать только ранее авторизованные аккаунты.Задайте идентификатор клиента сервера. Установите параметр
setServerClientId.webClientId– это идентификатор веб-клиента, который вы настроили для OAuth в проекте Google Cloud при выполнении предварительных требований.Включите автоматический вход (необязательно). Чтобы включить автоматический вход для вернувшихся пользователей, используйте
setAutoSelectEnabled(true)иsetFilterByAuthorizedAccounts(true). Это упрощает процесс входа для пользователей, которые уже входили в аккаунт ранее.Автоматический вход возможен только при соблюдении следующих условий:
- На устройстве есть только один авторизованный аккаунт, который ранее использовался для входа в приложение. Если на устройстве несколько авторизованных аккаунтов, автоматический вход будет отключен.
- Пользователь не вышел из аккаунта в приложении во время предыдущего сеанса.
- Пользователь не отключил автоматический вход в настройках аккаунта Google.
Укажите nonce (необязательно). Чтобы повысить уровень безопасности, задайте nonce для проверки на стороне сервера. Чтобы предотвратить атаки повторного воспроизведения, вы можете включить одноразовый код для проверки на стороне сервера с помощью
setNonce(). Убедитесь, что ваш серверный код проверяет, совпадают ли одноразовые коды запроса и ответа.Чтобы сгенерировать nonce, используйте функцию, похожую на приведенную ниже. Она генерирует криптографически стойкий случайный nonce заданной длины и кодирует его с помощью
Base64:
fun generateSecureRandomNonce(byteLength: Int = 32): String {
val randomBytes = ByteArray(byteLength)
SecureRandom().nextBytes(randomBytes)
return Base64.encodeToString(randomBytes, Base64.NO_WRAP or Base64.URL_SAFE or Base64.NO_PADDING)
}
Запросить вход в аккаунт
Проверьте, есть ли у пользователя авторизованный аккаунт на устройстве, вызвав метод getCredential:
val request: GetCredentialRequest = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
// Use an activity-based context to avoid undefined system UI
// launching behavior.
val mutableContext = MutableContextWrapper(activityContext)
coroutineScope {
try {
val result = credentialManager.getCredential(
request = request,
context = mutableContext // Use MutableContextWrapper to avoid memory leak during configuration changes
)
handleSignIn(result)
} catch (e: GetCredentialException) {
// Handle failures
}
}
Настройте запрос на вход, если нет доступных авторизованных аккаунтов
Если на устройстве нет авторизованных пользователей вашего приложения, CredentialManager возвращает NoCredentialException. В этом случае отключите фильтр авторизованных аккаунтов, чтобы пользователь мог зарегистрироваться с помощью другого аккаунта.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false)
.setServerClientId(WEB_CLIENT_ID)
.setNonce(generateSecureRandomNonce())
.build()
Затем запросите вход так же, как вы делали это для авторизованных аккаунтов.
Создайте процесс кнопки
Используйте кнопку, если хотите, чтобы пользователи могли входить с аккаунтом Google в следующих случаях:
- Пользователь закрыл нижний экран Менеджера учетных данных.
- На устройстве нет аккаунтов Google.
- Для существующих аккаунтов на устройстве требуется повторная аутентификация.
Создайте интерфейс кнопки
Хотя это можно сделать с помощью кнопки Jetpack Compose, вы можете использовать предварительно одобренный значок бренда со страницы Правила фирменного оформления функции "Войти с аккаунтом Google".
Создайте процесс входа
Создайте запрос на вход в Google с помощью GetSignInWithGoogleOption, чтобы получить токен идентификатора Google.
val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
serverClientId = WEB_CLIENT_ID
).setNonce(generateSecureRandomNonce())
.build()
Затем запросите вход так же, как вы это делали для нижнего экрана.
Создайте функцию общего входа для нижнего экрана и кнопки.
Чтобы настроить вход, выполните следующие действия:
- Используйте функцию
getCredential()в CredentialManager. Если ответ успешный, извлекитеCustomCredential, который должен иметь типGoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL. Преобразуйте объект в
GoogleIdTokenCredentialс помощью методаGoogleIdTokenCredential.createFrom().Проверьте учетные данные на сервере проверяющей стороны.
Убедитесь, что вы правильно обрабатываете ошибки.
fun handleSign(result: GetCredentialResponse) {
// Handle the successfully returned credential.
val credential = result.credential
when (credential) {
is CustomCredential -> {
if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
try {
// Use googleIdTokenCredential and extract the ID for server-side validation.
val googleIdTokenCredential = GoogleIdTokenCredential
.createFrom(credential.data)
} catch (e: GoogleIdTokenParsingException) {
Log.e(TAG, "Received an invalid google id token response", e)
}
} else {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential")
}
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential")
}
}
}
Обработка ошибок
Изучите ошибки, перечисленные в разделе Устранение неполадок, чтобы убедиться, что ваш код обрабатывает все возможные сценарии ошибок.
Как обрабатывать выход из аккаунта
Важно предоставить пользователям возможность выходить из аккаунта в вашем приложении. Например, у пользователя может быть несколько аккаунтов Google на устройстве, и он может захотеть войти в другой аккаунт. Например, вы можете добавить ее на страницу настроек.
Поставщик учетных данных может хранить активный сеанс учетных данных и использовать его, чтобы ограничивать способы входа для будущих запросов на вход. Например, оно может отдавать приоритет активным учетным данным перед другими доступными.
Когда пользователь выходит из приложения, вызовите метод API clearCredentialState(), чтобы удалить текущие учетные данные из всех поставщиков.
Это уведомит всех поставщиков учетных данных о том, что все сохраненные сеансы учетных данных для данного приложения должны быть очищены, что предоставит пользователям полные способы входа в следующий раз.