Реализуйте вход через Google.

В этом руководстве описывается, как реализовать вход через Google, и рассматриваются следующие шаги:

  • Добавьте зависимости в ваше приложение.
  • Создайте экземпляр CredentialManager .
  • Создайте поток данных на нижнем листе.
  • Создайте последовательность нажатия кнопок.
  • Обработайте ответ на запрос авторизации.
  • Обработка ошибок.
  • Обработайте выход из системы.

Добавьте зависимости в ваше приложение.

В файле build.gradle вашего модуля укажите зависимости, используя последнюю версию Credential Manager, Play Services Auth и googleid :

Котлин

dependencies {
    implementation("androidx.credentials:credentials:1.6.0-rc02")
    implementation("androidx.credentials:credentials-play-services-auth:1.6.0-rc02")
    implementation("com.google.android.libraries.identity.googleid:googleid:<latest version>")
}

Круто

dependencies {
    implementation "androidx.credentials:credentials:1.6.0-rc02"
    implementation "androidx.credentials:credentials-play-services-auth:1.6.0-rc02"
    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 для проверки на стороне сервера. Для предотвращения атак повторного воспроизведения вы можете включить nonce для проверки на стороне сервера с помощью setNonce() . Убедитесь, что ваш серверный код проверяет идентичность nonce запроса и ответа.

    Для генерации 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()

coroutineScope {
    try {
        val result = credentialManager.getCredential(
            request = request,
            context = activityContext,
        )
        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, вы также можете использовать предварительно одобренный значок бренда со страницы «Рекомендации по брендингу при входе через Google» .

Создайте процесс авторизации.

Создайте запрос на вход через Google с помощью GetSignInWithGoogleOption , чтобы получить токен идентификатора Google.

val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
    serverClientId = WEB_CLIENT_ID
).setNonce(generateSecureRandomNonce())
    .build()

Далее запросите авторизацию аналогично тому, как вы это делали для нижнего меню интерфейса.

Создайте функцию общего входа для нижнего окна и кнопки.

Для авторизации выполните следующие действия:

  1. Используйте функцию getCredential() из CredentialManager. Если ответ успешен, извлеките объект CustomCredential , который должен иметь тип GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL .
  2. Преобразуйте объект в объект GoogleIdTokenCredential используя метод GoogleIdTokenCredential.createFrom() .

  3. Проверьте учетные данные на сервере вашей доверенной стороны.

  4. Убедитесь, что вы надлежащим образом обрабатываете ошибки.

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() , чтобы очистить текущее состояние учетных данных пользователя у всех поставщиков учетных данных. Это уведомит всех поставщиков учетных данных о необходимости очистки всех сохраненных сессий учетных данных для данного приложения, предоставив пользователям полные возможности входа в систему при следующем входе.