Anmeldung über ein verknüpftes Konto für Android

Die Funktion „Anmeldung mit verknüpften Konten“ aktiviert Über Google anmelden über One Tap für Nutzer, die ihr Google-Konto bereits mit Ihrem Dienst verknüpft haben. Das erleichtert den Nutzern die Anmeldung, da sie sich mit nur einem Klick anmelden können, ohne ihren Nutzernamen und ihr Passwort noch einmal eingeben zu müssen. Außerdem verringert sich dadurch die Wahrscheinlichkeit, dass Nutzer doppelte Konten bei Ihrem Dienst erstellen.

Die Anmeldung über ein verknüpftes Konto ist als Teil des Anmeldevorgangs über One Tap für Android verfügbar. Das bedeutet, dass Sie keine separate Bibliothek importieren müssen, wenn die One Tap-Funktion für Ihre App bereits aktiviert ist.

In diesem Dokument erfahren Sie, wie Sie Ihre Android-App so anpassen, dass sie die Anmeldung über ein verknüpftes Konto unterstützt.

Funktionsweise

  1. Sie können festlegen, dass verknüpfte Konten während der Anmeldung über One Tap angezeigt werden.
  2. Wenn der Nutzer bei Google angemeldet ist und sein Google-Konto mit seinem Konto bei Ihrem Dienst verknüpft hat, wird für das verknüpfte Konto ein ID-Token zurückgegeben.
  3. Dem Nutzer wird eine Aufforderung zur Anmeldung über One Tap mit der Option angezeigt, sich mit seinem verknüpften Konto bei Ihrem Dienst anzumelden.
  4. Wenn der Nutzer sich entscheidet, mit dem verknüpften Konto fortzufahren, wird das ID-Token des Nutzers an deine App zurückgegeben. Du vergleichst dieses Token mit dem Token, das in Schritt 2 an deinen Server gesendet wurde, um den angemeldeten Nutzer zu identifizieren.

Einrichtung

Entwicklungsumgebung einrichten

Holen Sie sich die neuesten Google Play-Dienste auf Ihrem Entwicklungshost:

  1. Öffnen Sie den Android SDK Manager.
  1. Suchen Sie unter SDK-Tools nach Google Play-Dienste.

  2. Wenn der Status dieser Pakete nicht „Installiert“ lautet, wählen Sie beide aus und klicken Sie auf Install Packages (Pakete installieren).

Eigene App konfigurieren

  1. Fügen Sie in der Datei build.gradle auf Projektebene das Maven-Repository von Google in die Abschnitte buildscript und allprojects ein.

    buildscript {
        repositories {
            google()
        }
    }
    
    allprojects {
        repositories {
            google()
        }
    }
    
  2. Fügen Sie die Abhängigkeiten für die „Link with Google“ API in die Gradle-Datei auf App-Ebene Ihres Moduls ein, die normalerweise app/build.gradle ist:

    dependencies {
      implementation 'com.google.android.gms:play-services-auth:21.2.0'
    }
    

Ändern Sie Ihre Android-App so, dass sie die Anmeldung über ein verknüpftes Konto unterstützt

Am Ende des Anmeldevorgangs für ein verknüpftes Konto wird ein ID-Token an Ihre Anwendung zurückgegeben. Die Integrität des ID-Tokens sollte vor der Anmeldung des Nutzers überprüft werden.

Im folgenden Codebeispiel werden die Schritte zum Abrufen, Überprüfen des ID-Tokens und anschließender Anmeldung des Nutzers beschrieben.

  1. Erstellen Sie eine Aktivität, um das Ergebnis des Anmelde-Intents zu erhalten

    Kotlin

      private val activityResultLauncher = registerForActivityResult(
        ActivityResultContracts.StartIntentSenderForResult()) { result ->
        if (result.resultCode == RESULT_OK) {
          try {
            val signInCredentials = Identity.signInClient(this)
                                    .signInCredentialFromIntent(result.data)
            // Review the Verify the integrity of the ID token section for
            // details on how to verify the ID token
            verifyIdToken(signInCredential.googleIdToken)
          } catch (e: ApiException) {
            Log.e(TAG, "Sign-in failed with error code:", e)
          }
        } else {
          Log.e(TAG, "Sign-in failed")
        }
      }
    

    Java

      private final ActivityResultLauncher<IntentSenderResult>
        activityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartIntentSenderForResult(),
        result -> {
        If (result.getResultCode() == RESULT_OK) {
            try {
              SignInCredential signInCredential = Identity.getSignInClient(this)
                             .getSignInCredentialFromIntent(result.getData());
              verifyIdToken(signInCredential.getGoogleIdToken());
            } catch (e: ApiException ) {
              Log.e(TAG, "Sign-in failed with error:", e)
            }
        } else {
            Log.e(TAG, "Sign-in failed")
        }
    });
    
  2. Anmeldeanfrage erstellen

    Kotlin

    private val tokenRequestOptions =
    GoogleIdTokenRequestOptions.Builder()
      .supported(true)
      // Your server's client ID, not your Android client ID.
      .serverClientId(getString("your-server-client-id")
      .filterByAuthorizedAccounts(true)
      .associateLinkedAccounts("service-id-of-and-defined-by-developer",
                               scopes)
      .build()
    

    Java

     private final GoogleIdTokenRequestOptions tokenRequestOptions =
         GoogleIdTokenRequestOptions.Builder()
      .setSupported(true)
      .setServerClientId("your-service-client-id")
      .setFilterByAuthorizedAccounts(true)
      .associateLinkedAccounts("service-id-of-and-defined-by-developer",
                                scopes)
      .build()
    
  3. Intent „Sign-in Pending“ (Anmeldung ausstehend) starten

    Kotlin

     Identity.signInClient(this)
        .beginSignIn(
      BeginSignInRequest.Builder()
        .googleIdTokenRequestOptions(tokenRequestOptions)
      .build())
        .addOnSuccessListener{result ->
          activityResultLauncher.launch(result.pendingIntent.intentSender)
      }
      .addOnFailureListener {e ->
        Log.e(TAG, "Sign-in failed because:", e)
      }
    

    Java

     Identity.getSignInClient(this)
      .beginSignIn(
        BeginSignInRequest.Builder()
          .setGoogleIdTokenRequestOptions(tokenRequestOptions)
          .build())
      .addOnSuccessListener(result -> {
        activityResultLauncher.launch(
            result.getPendingIntent().getIntentSender());
    })
    .addOnFailureListener(e -> {
      Log.e(TAG, "Sign-in failed because:", e);
    });
    

Integrität des ID-Tokens prüfen

Prüfen Sie, ob die folgenden Kriterien erfüllt sind:

  • Das ID-Token ist ordnungsgemäß von Google signiert. Verwenden Sie die öffentlichen Schlüssel von Google (verfügbar im Format JWK oder PEM), um die Signatur des Tokens zu prüfen. Diese Schlüssel werden regelmäßig rotiert. Prüfen Sie den Cache-Control-Header in der Antwort, um festzustellen, wann Sie sie noch einmal abrufen sollten.
  • Der Wert von aud im ID-Token entspricht einer der Client-IDs der Anwendung. Diese Prüfung ist erforderlich, um zu verhindern, dass ID-Tokens, die an eine schädliche Anwendung gesendet wurden, für den Zugriff auf Daten desselben Nutzers auf dem Back-End-Server der Anwendung verwendet werden.
  • Der Wert von iss im ID-Token ist accounts.google.com oder https://accounts.google.com.
  • Die Ablaufzeit (exp) des ID-Tokens ist noch nicht verstrichen.
  • Wenn Sie überprüfen müssen, ob das ID-Token ein Google Workspace- oder Cloud-Organisationskonto darstellt, können Sie die hd-Anforderung prüfen, die die gehostete Domain des Nutzers angibt. Dies muss verwendet werden, wenn der Zugriff auf eine Ressource auf Mitglieder bestimmter Domains beschränkt werden soll. Falls dieser Anspruch fehlt, bedeutet das, dass das Konto nicht zu einer von Google gehosteten Domain gehört.

Anstatt eigenen Code zu schreiben, um diese Überprüfungsschritte auszuführen, empfehlen wir dringend, eine Google API-Clientbibliothek für Ihre Plattform oder eine allgemeine JWT-Bibliothek zu verwenden. Zur Entwicklung und Fehlerbehebung können Sie unseren Validierungsendpunkt tokeninfo aufrufen.

Google API-Clientbibliothek verwenden

Für die Validierung von Google-ID-Tokens in einer Produktionsumgebung wird die Google API-Clientbibliothek für Java empfohlen.

Java

  import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
  import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
  import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

  ...

  GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
      // Specify the CLIENT_ID of the app that accesses the backend:
      .setAudience(Collections.singletonList(CLIENT_ID))
      // Or, if multiple clients access the backend:
      //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
      .build();

  // (Receive idTokenString by HTTPS POST)

  GoogleIdToken idToken = verifier.verify(idTokenString);
  if (idToken != null) {
    Payload payload = idToken.getPayload();

    // Print user identifier
    String userId = payload.getSubject();
    System.out.println("User ID: " + userId);

    // Get profile information from payload
    String email = payload.getEmail();
    boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
    String name = (String) payload.get("name");
    String pictureUrl = (String) payload.get("picture");
    String locale = (String) payload.get("locale");
    String familyName = (String) payload.get("family_name");
    String givenName = (String) payload.get("given_name");

    // Use or store profile information
    // ...

  } else {
    System.out.println("Invalid ID token.");
  }

Die Methode GoogleIdTokenVerifier.verify() prüft die JWT-Signatur, die Anforderung aud, die Anforderung iss und die Anforderung exp.

Wenn Sie prüfen müssen, ob das ID-Token ein Google Workspace- oder Cloud-Organisationskonto darstellt, können Sie die hd-Anforderung verifizieren. Dazu prüfen Sie den Domainnamen, der von der Methode Payload.getHostedDomain() zurückgegeben wurde.

Tokeninfo-Endpunkt aufrufen

Eine einfache Möglichkeit zur Validierung einer ID-Token-Signatur für das Debugging ist die Verwendung des Endpunkts tokeninfo. Das Aufrufen dieses Endpunkts erfordert eine zusätzliche Netzwerkanfrage, die den Großteil der Validierung für Sie übernimmt, während Sie die ordnungsgemäße Validierung und die Extraktion der Nutzlast in Ihrem eigenen Code testen. Sie ist nicht für die Verwendung in Produktionscode geeignet, da Anfragen gedrosselt oder auf andere Weise zeitweilig auftretenden Fehlern ausgesetzt werden können.

Wenn Sie ein ID-Token mit dem Endpunkt tokeninfo validieren möchten, senden Sie eine HTTPS-POST- oder -GET-Anfrage an den Endpunkt und übergeben Sie Ihr ID-Token im Parameter id_token. Um beispielsweise das Token "XYZ123" zu validieren, führen Sie die folgende GET-Anfrage aus:

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

Wenn das Token ordnungsgemäß signiert ist und die Anforderungen iss und exp die erwarteten Werte haben, erhalten Sie eine HTTP 200-Antwort, in der der Text die ID-Token-Anforderungen im JSON-Format enthält. Sie sehen hier ein Beispiel:

{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

Wenn du überprüfen musst, ob das ID-Token ein Google Workspace-Konto darstellt, kannst du die hd-Anforderung prüfen, die die gehostete Domain des Nutzers angibt. Dies muss verwendet werden, wenn der Zugriff auf eine Ressource auf Mitglieder bestimmter Domains beschränkt werden soll. Falls dieser Anspruch fehlt, bedeutet das, dass das Konto nicht zu einer von Google Workspace gehosteten Domain gehört.