W tym przewodniku opisujemy, jak wdrożyć funkcję Zaloguj się przez Google. Obejmuje on te kroki:
- Dodaj zależności do aplikacji.
- Utwórz instancję
CredentialManager. - Utwórz proces planszy dolnej.
- Utwórz przepływ przycisku.
- Obsługa odpowiedzi na żądanie logowania.
- Obsługuj błędy.
- Obsługa wylogowywania.
Dodawanie zależności do aplikacji
W pliku build.gradle modułu zadeklaruj zależności, używając najnowszej wersji Credential Managera, uwierzytelniania w Usługach Google 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 Menedżera danych logowania
Użyj kontekstu aplikacji lub aktywności, aby utworzyć obiekt CredentialManager.
// 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 Manager. Korzystanie z tego interfejsu zapewnia spójne działanie wszystkich metod uwierzytelniania, takich jak hasła, klucze dostępu i Zaloguj się przez Google.
Konfigurowanie prośby o zalogowanie się na wcześniej autoryzowanych kontach
Spróbuj wysłać żądanie logowania przez Google za pomocą GetGoogleIdOption, aby pobrać token identyfikacji Google użytkownika.
Te 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:
Filtrowanie wcześniej autoryzowanych kont: aby pobrać autoryzowane konta, które były wcześniej używane do logowania się w aplikacji, ustaw
setFilterByAuthorizedAccountsnatrue.Pamiętaj, że domyślna wartość parametru
setFilterByAuthorizedAccountstotrue, co oznacza, że domyślnie w interfejsie planszy dolnej wyświetlane są tylko wcześniej autoryzowane konta.Ustaw identyfikator klienta serwera: ustaw parametr
setServerClientId.webClientIdto identyfikator klienta usługi internetowej skonfigurowany na potrzeby protokołu OAuth w projekcie Google Cloud podczas wykonywania wymagań wstępnych.Włączanie logowania automatycznego (opcjonalnie): aby włączyć logowanie automatyczne dla powracających użytkowników, użyj
setAutoSelectEnabled(true)isetFilterByAuthorizedAccounts(true). Dzięki temu użytkownicy aplikacji, którzy byli już wcześniej zalogowani, nie muszą wykonywać niepotrzebnych czynności.Logowanie automatyczne jest możliwe tylko wtedy, gdy spełnione są te kryteria:
- na urządzeniu jest tylko jedno autoryzowane konto, które było wcześniej używane do logowania się w aplikacji na urządzeniu; Jeśli na urządzeniu jest kilka autoryzowanych kont, logowanie automatyczne jest wyłączone.
- Użytkownik nie wylogował się z aplikacji podczas poprzedniej sesji.
- Użytkownik nie wyłączył logowania automatycznego w ustawieniach konta Google.
Ustaw liczbę jednorazową (opcjonalnie): aby zwiększyć bezpieczeństwo, ustaw liczbę jednorazową na potrzeby weryfikacji po stronie serwera. Aby zapobiec atakom typu replay, możesz dołączyć liczbę jednorazową do weryfikacji po stronie serwera za pomocą
setNonce(). Upewnij się, że kod po stronie serwera sprawdza, czy liczby jednorazowe żądania i odpowiedzi są identyczne.Aby wygenerować liczbę jednorazową, użyj funkcji podobnej do tej, która generuje kryptograficznie silną losową liczbę jednorazową o określonej długości i koduje ją 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)
}
Prośba o zalogowanie się
Sprawdź, czy użytkownik ma autoryzowane konto na urządzeniu, 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ę, gdy 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 taki sam sposób jak w przypadku autoryzowanych kont.
Tworzenie przepływu przycisku
Użyj przycisku, jeśli chcesz, aby użytkownicy mogli korzystać z funkcji Zaloguj się przez Google w tych przypadkach:
- Użytkownik zamknął interfejs dolnej planszy Credential Manager.
- Na urządzeniu nie ma kont Google.
- Konta istniejące na urządzeniu wymagają ponownego uwierzytelnienia.
Tworzenie interfejsu przycisku
Można 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 procesu logowania
Utwórz żądanie logowania 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 funkcji wspólnego logowania na potrzeby planszy dolnej i przycisku
Aby obsłużyć logowanie, wykonaj te czynności:
- Użyj funkcji
getCredential()interfejsu CredentialManager. Jeśli odpowiedź jest prawidłowa, wyodrębnijCustomCredential, który powinien być typuGoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL. Przekonwertuj obiekt na
GoogleIdTokenCredentialza pomocą metodyGoogleIdTokenCredential.createFrom().Zweryfikuj dane logowania na serwerze strony zależnej.
Upewnij się, że odpowiednio 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ługuj błędy
Przejrzyj błędy wymienione w sekcji Rozwiązywanie problemów, aby upewnić się, że kod obsługuje wszystkie możliwe scenariusze błędów.
Obsługa wylogowywania
Ważne jest, aby zapewnić użytkownikom mechanizm wylogowywania się z aplikacji. Na przykład użytkownik może mieć na urządzeniu kilka kont Google i zdecydować się na zalogowanie się z innego konta. Możesz to zrobić na przykład na stronie ustawień.
Dostawca danych logowania może przechowywać aktywną sesję danych logowania i używać jej do ograniczania opcji logowania w przypadku przyszłych żądań logowania. Może na przykład nadać aktywnym danym logowania priorytet nad innymi dostępnymi danymi logowania.
Gdy użytkownik wyloguje się z aplikacji, wywołaj metodę interfejsu API clearCredentialState(), aby wyczyścić bieżący stan danych logowania użytkownika u wszystkich dostawców danych logowania.
Spowoduje to powiadomienie wszystkich dostawców danych logowania, że wszystkie zapisane sesje danych logowania dla danej aplikacji powinny zostać wyczyszczone, co zapewni użytkownikom pełne opcje logowania przy następnym logowaniu.