直接从您的平台发起 Google 账号关联。

关联帐号可以直接在移动应用中完成,这样您就可以让用户将您服务的帐号与 Google 帐号相关联。建立的关联可向 Google 授予用户同意共享的数据的访问权限。

用户可享有的优势包括:

  • 用户可以在您的应用中开始并完成帐号关联流程,这是他们熟悉的环境。
  • 用户无需登录凭据,因为已在设备和您的移动应用中通过身份验证。

开发者获得的好处包括:

  • 在移动应用中(例如,在用户设置中,在插页式广告上或用户登录移动应用后)宣传和启动帐号关联,以提高互动度和关联的帐号数量。
  • 转化率有所提高,因为用户可以完成的步骤比基于网络的标准 OAuth 流程少。
  • 实现您的平台 (Android) 链接的工程工作量很少,因为此流程已利用您现有的 OAuth2.0 实现(假设您已实现一个)。
  • 提升了用户流失率,因为用户无需重新输入登录凭据,用更少的步骤就能完成此流程。 在要求用户召回和输入登录凭据的流程中,流失率可能高达 80%。

How it works

Link from your Platform is completed in the following steps:

  1. User will click / toggle a linking trigger on your mobile app.
  2. The user selects the Google Account to link.
    1. The user selects an existing Google Account on the device to link, or signs in with a new account
  3. The user is shown a Google hosted consent screens and has to agree to continue or cancel to stop the linking process.
  4. The user is shown your consent screen and has to agree to continue or cancel to stop the linking process.
  5. The Link is established between the user’s account, on your service, and their Google Account.

Figure 1. Link from your Platform Flow

Requirements

To implement Link from your platform, you need the following:

  • An android app.
  • Own, manage, and maintain an OAuth 2.0 server that supports the OAuth 2.0 authorization code flow.

Setup

Before proceeeding with the steps below, you must have completed the Account Linking registration process.

Setup your development environment

Get the latest Google Play services on your development host:

  1. Open the Android SDK Manager.
  1. Under SDK Tools, find Google Play services.

  2. If the status for these packages is not Installed, select them both and click Install Packages.

Configure your app

  1. In your project-level build.gradle file, include Google's Maven repository in both your buildscript and allprojects sections.

    buildscript {
        repositories {
            google()
        }
    }
    
    allprojects {
        repositories {
            google()
        }
    }
    
  2. Add the dependencies for the “Link with Google” API to your module's app-level gradle file, which is usually app/build.gradle:

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

The Link from your Platform flow will result in an access token, provided by your service, being saved by Google. Consent must be received before returning the token for the user.

Follow the steps below to get consent from the user and return an auth code token via the Google Play Services SDK.

  1. Build a PendingIntent that can launch your consent activity - The consent is launched by the Play Services API. You will need to provide a PendingIntent (which will be referred to as the consentPendingIntent for clarity) when the API is called

    Kotlin

    // Build a PendingIntent that can launch the consent activity
    val consentPendingIntent = buildConsentPendingIntent()
    

    Java

    // Build a PendingIntent that can launch your consent activity
    PendingIntent consentPendingIntent =
              buildConsentPendingIntent();
    
  2. Create corresponding Activity to handle the consent intent

    Kotlin

      class ConsentActivity : AppCompatActivity
    
      private fun onConsentAccepted() {
          // Obtain a token (for simplicity, we’ll ignore the async nature
          // of the following call)
          val token = getToken()
          val intent = Intent()
                      .putExtra(SaveAccountLinkingTokenRequest.EXTRA_TOKEN,
                                token)
          setResult(Activity.RESULT_OK, intent)
          finish()
      }
    
      private fun onConsentRejectedOrCanceled() {
          setResult(Activity.RESULT_CANCELED)
          finish()
      }
    

    Java

      public class ConsentActivity extends AppCompatActivity {
        ...
        private void onConsentAccepted() {
          // Obtain a token (for simplicity, we’ll ignore the async nature of
          // the following call
          String token = getToken();
          Intent intent = new Intent();
          intent.putExtra(SaveAccountLinkingTokenRequest.EXTRA_TOKEN, token);
          setResult(Activity.RESULT_OK, intent);
          finish();
        }
    
        private void onConsentRejectedOrCanceled() {
          setResult(Activity.RESULT_CANCELED, null);
          finish();
        }
     }
    
    

    We assume that the methods onConsentAccpeted() and onConsentRejectedOrCanceled() are called if user accepts or rejects/cancels your consent, respectively.

  3. Create a request for saving the token and, among other configuration parameters, pass the PendingIntent created in step 1 above.

    Kotlin

      // Create an ActivityResultLauncher which registers a callback for the
      // Activity result contract
      val activityResultLauncher = registerForActivityResult(
        ActivityResultContracts.StartIntentSenderForResult())
        { result ->
          if (result.resultCode == RESULT_OK) {
            // Successfully finished the flow and saved the token
          } else {
            // Flow failed, for example the user may have canceled the flow
          }
        }
    
      // Build token save request
      val request = SaveAccountLinkingTokenRequest.builder()
        .setTokenType(SaveAccountLinkingTokenRequest.TOKEN_TYPE_AUTH_CODE)
        .setConsentPendingIntent(consentPendingIntent)
        .setServiceId("service-id-of-and-defined-by-developer")
        //Set the scopes that the token is valid for on your platform
        .setScopes(scopes)
        .build()
    
       // Launch consent activity and retrieve token
       Identity.getCredentialSavingClient(this)
         .saveAccountLinkingToken(request)
         .addOnSuccessListener( saveAccountLinkingTokenResult -> {
            if (saveAccountLinkingTokenResult.hasResolution()) {
              val pendingIntent = saveAccountLinkingTokenResult
                                  .getPendingIntent()
              val intentSenderRequest = IntentSenderRequest
                                        .Builder(pendingIntent).build()
              activityResultLauncher.launch(intentSenderRequest)
            } else {
               // This should not happen, let’s log this
               Log.e(TAG, "Failed to save token");
            }
          })
          .addOnFailureListener(e -> Log.e(TAG, Failed to save token, e))
    

    Java

      // Create an ActivityResultLauncher which registers a callback for the
      // Activity result contract
      ActivityResultLauncher<IntentSenderRequest>
          activityResultLauncher =
          registerForActivityResult(new ActivityResultContracts
                                        .StartIntentSenderForResult(),
                                    result -> {
          if (result.getResultCode() == RESULT_OK) {
              // Successfully finished the flow and saved the token
          } else {
              // Flow failed, for example the user may have canceled the flow
          }
      });
    
     // Build token save request
     SaveAccountLinkingTokenRequest request =
        SaveAccountLinkingTokenRequest.builder()
            .setTokenType(
                SaveAccountLinkingTokenRequest.TOKEN_TYPE_AUTH_CODE)
            .setConsentPendingIntent(consentPendingIntent)
            .setServiceId("service-id-of-and-defined-by-developer")
            //Set the scopes that the token is valid for on your platform
            .setScopes(scopes)
            .build();
    
      // Launch consent activity and retrieve token
      Identity.getCredentialSavingClient(this)
          .saveAccountLinkingToken(request)
          .addOnSuccessListener(
              saveAccountLinkingTokenResult -> {
                if (saveAccountLinkingTokenResult.hasResolution()) {
                  // Launch the resolution intent
                  PendingIntent pendingIntent =
                      saveAccountLinkingTokenResult.getPendingIntent();
                  IntentSenderRequest intentSenderRequest =
                      new IntentSenderRequest.Builder(pendingIntent).build();
                  activityResultLauncher.launch(intentSenderRequest);
                } else {
                  // This should not happen, let’s log this
                  Log.e(TAG, "Failed to save token");
                }
              })
          .addOnFailureListener(e -> Log.e(TAG, "Failed to save token", e));
      ```
    

The above steps prompts a user for consent and returns an authorization code to Google.

Best Practices

  • Your app should indicate link status to the user through a button, toggle or a similar visual element.

    Figure 1. Sample link status image

  • You should notify the user after a successful link e.g. display a toast, trigger a toggle state change or redirect the user to a separate link success page.

  • You should consider prompting in-app users to link accounts, ideally based on strong signals that linking would benefit such users.

  • After successfully linking, you should give users an example of what to do with the linked account e.g. if you just linked a music streaming service, ask your Google Assistant to play music.

  • Enable users to manage their linked accounts, including the option to unlink them. Point them to their Google Linked Accounts management page, that is, https://myaccount.google.com/accountlinking.

Reference

Android auth api reference documentation