Initiate Google Account Linking directly from your platform.

Account Linking can be completed directly within your mobile app, allowing your users to link their account on your service with their Google Account. The established link grants Google access to the data the user consents to share.

Benefits for users include:

  • Users can start and complete the account linking process in your app, an environment they are already familiar with.
  • Users do not require login credentials because they have already been authenticated on the device and in your mobile app.

Benefits for developers include:

  • Control where to promote and initiate account linking in your mobile app, for example, in user settings, on interstitials or after a user signs in to your mobile app. Adding multiple entry points to initiate account linking helps make account linking more discoverable, resulting in increased engagement and number of linked accounts.
  • Increase in the conversion rate as users are able to complete the linking process in fewer steps than the standard web-based OAuth flow.
  • Low engineering effort required to implement Link from your Platform (Android) because this flow leverages your existing OAuth2.0 implementation, assuming you already have one implemented.
  • Reduced drop-off rates because users do not need to re-enter their login credentials and are able to complete the process in fewer steps. Drop-off rates can be as high as 80% in flows where users are required to recall and enter their sign-in credentials.

工作原理

通过平台完成关联的步骤如下:

  1. 用户将在您的移动应用中点击 / 切换关联触发器。
  2. 用户选择要关联的 Google 帐号。
    1. 用户选择关联的现有 Google 帐号,或使用新帐号登录
  3. 系统会向用户显示 Google 托管的同意屏幕,用户必须同意继续或取消,才能停止关联过程。
  4. 系统会显示您的同意屏幕,用户必须同意继续或取消,才能停止关联过程。
  5. 该关联是在用户帐号、您的服务与其 Google 帐号之间建立的。

图 1. 从平台流程中创建关联

要求

如需从平台实现链接,您需要符合以下条件:

  • Android 应用。
  • 拥有、管理和维护支持 OAuth 2.0 授权代码流的 OAuth 2.0 服务器。

设置

您必须先完成帐号关联注册流程,然后才能继续执行以下步骤。

设置开发环境

在开发主机上获取最新的 Google Play 服务:

  1. 打开 Android SDK 管理器
  1. SDK Tools 下,找到 Google Play 服务

  2. 如果这些软件包的状态为“未安装”,请将其同时选中,然后点击安装软件包

配置您的应用

  1. 在项目级 build.gradle 文件中的 buildscriptallprojects 部分添加 Google 的 Maven 代码库。

    buildscript {
        repositories {
            google()
        }
    }
    
    allprojects {
        repositories {
            google()
        }
    }
    
  2. 将“Link with Google”API 的依赖项添加到您的模块的应用级 Gradle 文件(通常为 app/build.gradle):

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

您的平台流程中的链接会导致 Google 保存您的服务提供的访问令牌。必须先征得用户同意,然后才能为用户返回令牌。

请按照以下步骤征得用户同意,并通过 Google Play 服务 SDK 返回身份验证令牌。

  1. 构建可以启动用户同意活动的 PendingIntent - 用户意见由 Play 服务 API 启动。调用该 API 时,您需要提供 PendingIntent(为清楚起见,我们将称之为 consentPendingIntent

    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. 创建相应的 Activity 来处理用户意见征求 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();
        }
     }
    
    

    假设用户分别接受或拒绝/取消同意,系统会调用 onConsentAccpeted()onConsentRejectedOrCanceled() 方法。

  3. 创建保存令牌的请求,以及其他配置参数,并传递在第 1 步中创建的 PendingIntent

    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));
      ```
    

上述步骤会提示用户同意并将授权代码返回给 Google。

最佳做法

  • 您的应用应通过按钮、切换开关或类似视觉元素向用户显示链接状态。

    图 1. 链接状态图片示例

  • 您应该在成功关联后通知用户,例如显示消息框、触发切换状态更改或将用户重定向到单独的链接成功页面。

  • 您应该考虑提醒应用内用户关联帐号,最好依据有力的信号表明关联会让这些用户受益。

  • 成功关联后,您应该为用户提供一个示例,说明如何使用关联的帐号执行操作。例如,如果您刚刚关联了一款音乐在线播放服务,可以请 Google 助理播放音乐。

  • 允许用户管理关联的帐号,包括取消关联选项。引导他们访问“已关联的 Google 帐号”页面,即 https://myaccount.google.com/accountlinking。

参考

Android Auth API 参考文档