关联帐号可以直接在移动应用中完成,这样您就可以让用户将您服务的帐号与 Google 帐号相关联。建立的关联可向 Google 授予用户同意共享的数据的访问权限。
这种方法可在用户熟悉的应用情境中(而非在 Google 助理对话中)吸引用户,从而提高账号关联效果。它可以集成到用户入门、设置和其他应用界面中,从而为用户发现和使用您的 Google 助理 Action 创造机会。例如,关联后,您可以提供将用户直接带到您的 Action 的选项。
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.
运作方式
从平台进行关联的步骤如下:
- 用户将在您的移动应用中点击 / 切换关联触发器。
- 用户选择要关联的 Google 账号。
- 用户选择设备上现有的 Google 账号进行关联,或使用新账号登录
- 系统会向用户显示 Google 托管的意见征求界面,用户必须同意才能继续,或取消以停止关联流程。
- 系统会向用户显示您的同意屏幕,用户必须同意才能继续操作,否则必须取消才能停止关联流程。
- 在用户在您的服务中的账号与其 Google 账号之间建立关联。
图 1. 从平台流程链接
要求
如需从您的平台实现 Link,您需要满足以下条件:
- Android 应用。
- 拥有、管理和维护支持 OAuth 2.0 授权代码流程的 OAuth 2.0 服务器。
设置
在继续执行以下步骤之前,您必须已完成账号关联注册流程。
设置开发环境
在开发宿主上获取最新的 Google Play 服务:
- 打开 Android SDK 管理器。
在 SDK Tools 下,找到 Google Play services。
如果这些软件包的状态不是“已安装”,请同时选择这两个软件包,然后点击安装软件包。
配置您的应用
在您的项目级
build.gradle文件中,同时在buildscript和allprojects两个部分中添加 Google 的 Maven 代码库。buildscript { repositories { google() } } allprojects { repositories { google() } }将“与 Google 关联”API 的依赖项添加到模块的应用级 Gradle 文件(通常为
app/build.gradle)中:dependencies { implementation 'com.google.android.gms:play-services-auth:21.5.0' }
添加了对平台链接的支持
通过平台流程建立关联后,Google 会保存您的服务提供的访问令牌。必须先征得用户同意,然后才能返回用户令牌。
按照以下步骤操作,通过 Google Play 服务 SDK 获取用户同意并返回授权代码令牌。
构建可启动意见征求 activity 的 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();创建相应的 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()。创建一个用于保存令牌的请求,并在其他配置参数中传递在上述第 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. 链接状态图片示例
成功关联后,您应通知用户,例如显示 Toast 消息、触发切换状态更改或将用户重定向到单独的关联成功页面。
您应考虑提示应用内用户关联账号,最好是根据强信号判断关联账号会给这些用户带来好处。
成功关联后,您应向用户提供有关如何使用关联账号的示例,例如,如果您刚刚关联了音乐在线播放服务,请让 Google 助理播放音乐。
允许用户管理其关联的账号,包括提供解除关联的选项。引导用户前往其 Google 关联账号管理页面,即 https://myaccount.google.com/accountlinking。