Wdrażanie funkcji Zaloguj się przez Google

Ten przewodnik opisuje, jak zaimplementować Zaloguj się przez Google, i obejmuje te kroki:

  • Dodawanie zależności do aplikacji.
  • Tworzenie instancji CredentialManager.
  • Tworzenie przepływu planszy dolnej.
  • Tworzenie przepływu przycisku.
  • Obsługa odpowiedzi na logowanie.
  • Obsługa błędów.
  • Obsługa wylogowania.

Dodawanie zależności do aplikacji

W pliku build.gradle modułu zadeklaruj zależności, używając najnowszej wersji Credential Managera, pakietu SDK uwierzytelniania w Usługach Play i googleid:

Kotlin

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

Groovy

dependencies {
    implementation "androidx.credentials:credentials:1.7.0-alpha02"
    implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha02"
    implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>"
}

Tworzenie instancji Credential Managera

Aby utworzyć obiekt CredentialManager, użyj kontekstu aplikacji lub aktywności.

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)

Tworzenie przepływu planszy dolnej

Plansza dolna to wbudowany interfejs Credential Managera. Dzięki temu interfejsowi użytkownika wszystkie metody uwierzytelniania, takie jak hasła, klucze dostępu i Zaloguj się przez Google, zapewniają spójne wrażenia.

Konfigurowanie prośby o zalogowanie się na wcześniej autoryzowanych kontach

Spróbuj wysłać prośbę o zalogowanie się przez Google za pomocą GetGoogleIdOption aby pobrać token identyfikatora Google użytkownika.

Poniższe fragmenty kodu sprawdzają, czy konto jest autoryzowane.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(true)
    .setServerClientId(WEB_CLIENT_ID)
    .setAutoSelectEnabled(true)
    .setNonce(generateSecureRandomNonce())
    .build()

Obiekt żądania googleIdOption jest skonfigurowany w ten sposób:

  • Filtruj wcześniej autoryzowane konta: aby pobrać autoryzowane konta, które były wcześniej używane do logowania się w Twojej aplikacji, ustaw setFilterByAuthorizedAccounts na true.

    Pamiętaj, że domyślna wartość setFilterByAuthorizedAccounts to true, co oznacza, że domyślnie w interfejsie planszy dolnej wyświetlane są tylko wcześniej autoryzowane konta.

  • Ustaw identyfikator klienta serwera: ustaw parametr setServerClientId. webClientId to identyfikator klienta usługi internetowej skonfigurowany na potrzeby OAuth w projekcie Google Cloud podczas wykonywania wymagań wstępnych.

  • Włącz logowanie automatyczne (opcjonalnie): aby włączyć logowanie automatyczne dla powracających użytkowników, użyj setAutoSelectEnabled(true) i setFilterByAuthorizedAccounts(true). Dzięki temu użytkownicy aplikacji nie będą musieli się logować, jeśli już to zrobili.

    Logowanie automatyczne jest możliwe tylko wtedy, gdy spełnione są te kryteria:

    • Na urządzeniu jest tylko 1 autoryzowane konto, które było wcześniej używane do logowania się w aplikacji na tym urządzeniu. Jeśli na urządzeniu jest kilka autoryzowanych kont, automatyczne logowanie jest wyłączone.
    • Użytkownik nie wylogował się z aplikacji podczas poprzedniej sesji.
    • Użytkownik nie wyłączył automatycznego logowania w ustawieniach konta Google.
  • Ustaw nonce (opcjonalnie): aby zwiększyć bezpieczeństwo, ustaw nonce na potrzeby weryfikacji po stronie serwera. Aby zapobiec atakom typu replay, możesz dołączyć nonce na potrzeby weryfikacji po stronie serwera za pomocą setNonce(). Upewnij się, że kod po stronie serwera sprawdza, czy nonce w żądaniu i odpowiedzi są identyczne.

    Aby wygenerować nonce, użyj funkcji podobnej do tej, która generuje kryptograficznie silny losowy nonce o określonej długości i koduje go za pomocą 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)
}

Poproś o zalogowanie się

Sprawdź, czy użytkownik ma na urządzeniu autoryzowane konto, wywołując metodę 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
    }
}

Konfigurowanie prośby o zalogowanie się, jeśli nie ma dostępnych autoryzowanych kont

Jeśli na urządzeniu nie ma autoryzowanych użytkowników Twojej aplikacji, CredentialManager zwraca NoCredentialException. W takim przypadku wyłącz filtr autoryzowanych kont, aby użytkownik mógł zarejestrować się za pomocą innego konta.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(false)
    .setServerClientId(WEB_CLIENT_ID)
    .setNonce(generateSecureRandomNonce())
    .build()

Następnie poproś o zalogowanie się w podobny sposób jak w przypadku autoryzowanych kont.

Tworzenie przepływu przycisku

Użyj przycisku, jeśli chcesz, aby użytkownicy mogli Zalogować się przez Google w tych przypadkach:

  • Użytkownik zamknął interfejs planszy dolnej Credential Managera.
  • Na urządzeniu nie ma kont Google.
  • Istniejące konta na urządzeniu wymagają ponownego uwierzytelnienia.

Tworzenie interfejsu przycisku

Możesz to zrobić za pomocą przycisku Jetpack Compose, ale możesz też użyć wstępnie zatwierdzonej ikony marki ze strony Wytyczne dotyczące marki Zaloguj się przez Google.

Tworzenie przepływu logowania

Utwórz prośbę o zalogowanie się przez Google za pomocą GetSignInWithGoogleOption, aby pobrać token identyfikatora Google.

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

Następnie poproś o zalogowanie się w podobny sposób jak w przypadku interfejsu planszy dolnej.

Tworzenie wspólnej funkcji logowania na potrzeby planszy dolnej i przycisku

Aby obsługiwać logowanie, wykonaj te czynności:

  1. Użyj funkcji getCredential() Credential Managera. Jeśli odpowiedź jest prawidłowa, wyodrębnij CustomCredential, który powinien być typu GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.
  2. Przekonwertuj obiekt na GoogleIdTokenCredential za pomocą metody GoogleIdTokenCredential.createFrom().

  3. Zweryfikuj dane logowania na serwerze jednostki uzależnionej.

  4. Upewnij się, że prawidłowo obsługujesz błędy.

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")
        }
    }
}

Obsługa błędów

Zapoznaj się z błędami wymienionymi w sekcji Rozwiązywanie problemów, aby mieć pewność, że Twój kod obsługuje wszystkie możliwe scenariusze błędów.

Obsługa wylogowania

Ważne jest, aby zapewnić użytkownikom możliwość wylogowania się z aplikacji. Użytkownik może na przykład mieć na urządzeniu kilka kont Google i zdecydować się na zalogowanie się na inne konto. Możesz to zrobić np. na stronie ustawień.

Dostawca danych logowania może przechowywać aktywną sesję danych logowania i używać jej do ograniczania opcji logowania w przyszłych żądaniach logowania. Może na przykład traktować aktywne dane logowania jako priorytetowe w stosunku do innych dostępnych danych logowania.

Gdy użytkownik wyloguje się z Twojej aplikacji, wywołaj metodę interfejsu API clearCredentialState() , aby usunąć stan bieżących danych logowania użytkownika ze wszystkich dostawców danych logowania. Spowoduje to powiadomienie wszystkich dostawców danych logowania, że należy usunąć wszystkie zapisane sesje danych logowania dla danej aplikacji, co zapewni użytkownikom pełne opcje logowania przy następnym logowaniu.