拥有 OAuth 2.0 实现后,您可以选择配置基于 OAuth 的App Flip,这可让您的 Android 用户更快地将其在您的身份验证系统中的账号关联到他们的 Google 账号。以下部分介绍了如何为 Android 上的 Cloud-to-cloud 集成设计和实现 App Flip。
设计准则
本部分介绍了应用翻转账号关联同意屏幕的设计要求和建议。在 Google 调用您的应用后,您的应用会向用户显示同意屏幕。
要求
- 您必须提供 Google 授权声明,例如“关联后,Google 将有权控制您的设备。”
- 您必须告知用户,其账号将与 Google 关联,而非与 Google Home 或 Google 助理等特定 Google 产品关联。
- 您必须在意见征求界面上明确说明号召性用语,并使用“同意并关联”字样来表示关联操作。这是因为用户需要了解他们必须与 Google 共享哪些数据才能关联账号。
- 如果用户选择不关联,您必须提供一种让用户返回、拒绝或取消的方式。使用“取消”一词表示取消操作。
- 您必须实现以下工作流:用户点击“同意并关联”后,您必须显示关联成功消息,并自动将用户重定向回 Google Home 应用。用户现在应该会在 Google Home 应用中看到与您的操作相关联的设备。点击“取消”后,您应将用户重定向回 Google Home 应用。
建议
建议您执行以下操作:
显示 Google 的隐私权政策。在意见征求屏幕上添加指向 Google 隐私权政策的链接。
要分享的数据。使用简洁明了的语言告知用户 Google 需要哪些用户数据以及原因。
能够解除关联。提供一种可供用户取消关联的机制,例如指向您平台上的账号设置的网址。或者,您也可以添加指向 Google 账号的链接,以便用户管理其关联的账号。
能够更改用户账号。建议用户切换账号的方法。如果用户倾向于使用多个账号,此功能尤其有用。
- 如果用户必须关闭同意屏幕才能切换账号,请向 Google 发送可恢复的错误,以便用户可以通过 OAuth 关联和隐式流程登录所需账号。
添加您的徽标。在权限请求页面上显示公司徽标。 根据样式指南放置徽标。如果您还想显示 Google 的徽标,请参阅徽标和商标。
基于 OAuth 的 App Flip 的设置
以下部分描述了基于 OAuth 的 App Flip 的前提条件,以及如何在 Google Home Developer Console 中配置 App Flip 项目。
创建云到云集成并设置 OAuth 2.0 服务器
如需配置 App Flip,你需要先执行以下操作:
- 设置 OAuth 2.0 服务器。如需详细了解如何设置 OAuth 服务器,请参阅实现 OAuth 2.0 服务器。
- 创建云到云集成。如需创建集成,请按照创建云到云集成中的说明操作。
在开发者控制台中配置 App Flip
以下部分介绍了如何在开发者控制台中配置 App Flip。
- 填写账号关联下的所有必填(*) 字段。(如果不支持 App Flip,则会使用常规 OAuth 作为后备选项。)
- 为云端执行网址提供网址。云端执行方式网址用于处理智能家居 intent。勾选本地执行方式。
- 在 App Flip(可选)下方,选中 Android 应用。
- 填写以下字段:
- 应用 ID。应用 ID 是您为应用设置的唯一 ID。
- App signature。Android 应用必须先使用公钥证书进行“签名”,然后才能安装。如需了解如何获取应用签名,请参阅对客户端进行身份验证。
- Authorization intent。在此字段中,输入一个指定 intent 操作的字符串。
- 如果您想选择配置客户端,请添加范围,然后点击范围(可选)下的添加范围。
- 如果您的客户端需要,请选择允许 Google 通过 HTTP 基本 Auth 标头来传输客户端 ID 和客户端密钥。
现在,您可以继续阅读下一部分,在 Android 应用中实现 App Flip。
在原生应用中实现 App Flip
如需实现App Flip,您需要修改应用中的用户授权代码,以接受来自 Google 的深层链接。
基于 OAuth 的 App Flip 关联(App Flip)会将您的 Android 应用插入到 Google 账号关联流程中。传统的账号关联流程要求用户在浏览器中输入其凭据。使用 App Flip 可将用户登录操作推迟到您的 Android 应用中,从而让您能够利用现有授权。如果用户已登录您的应用,则无需重新输入凭据即可关联其账号。在 Android 应用中实现 App Flip 只需要对代码进行极少量的更改。
在本文档中,您将学习如何修改 Android 应用以支持 App Flip。
试用示例
App Flip 关联示例应用演示了 Android 上与 App Flip 兼容的账号关联集成。您可以使用此应用来验证如何响应来自 Google 移动应用的传入 App Flip intent。
示例应用已预先配置为与 App Flip Test Tool for Android 集成,您可以使用该工具验证 Android 应用与 App Flip 的集成,然后再配置与 Google 的账号关联。此应用会模拟启用 App Flip 时由 Google 移动应用触发的 intent。
运作方式
如需执行 App Flip 集成,必须按以下步骤操作:
- Google 应用会使用应用的软件包名称检查应用是否已安装在设备上。
- Google 应用会使用软件包签名检查来验证已安装的应用是否为正确的应用。
- Google 应用会构建一个 intent,用于在您的应用中启动指定 activity。此 intent 包含关联所需的其他数据。它还会通过 Android 框架解析此 intent,以检查您的应用是否支持 App Flip。
- 您的应用会验证请求是否来自 Google 应用。为此,您的应用会检查软件包签名和提供的客户端 ID。
- 您的应用向 OAuth 2.0 服务器请求授权代码。此流程结束时,它会向 Google 应用返回授权代码或错误。
- Google 应用会检索结果并继续进行账号关联。如果提供了授权代码,则令牌交换会在服务器之间进行,就像在基于浏览器的 OAuth 关联流程中一样。
修改 Android 应用以支持 App Flip
如需支持 App Flip,请对您的 Android 应用进行以下代码更改:
向
AndroidManifest.xml文件中添加一个<intent-filter>,其操作字符串与您在 App Flip intent 字段中输入的值一致。<activity android:name="AuthActivity"> <!-- Handle the app flip intent --> <intent-filter> <action android:name="INTENT_ACTION_FROM_CONSOLE"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>验证调用应用的签名。
您需要匹配用户可能用于账号关联的所有 Google 应用的软件包名称和签名。例如,如需与 Google Home 和 Google 搜索应用关联,请添加其软件包名称和签名:
- 软件包名称:
com.google.android.apps.chromecast.app - 原始 SHA-256 沿袭证书:
3D:7A:12:23:01:9A:A3:9D:9E:A0:E3:43:6A:B7:C0:89:6B:FB:4F:B6:79:F4:DE:5F:E7:C2:3F:32:6C:8F:99:4A - 轮替后的 Play 应用签名 SHA-256 证书:
5A:AD:2B:EE:6D:B9:5D:17:E0:5A:08:D7:D1:E6:4C:10:A1:51:18:79:15:44:83:91:6B:6A:E6:C7:FD:9C:B0:C6
和
- 软件包名称:
com.google.android.googlequicksearchbox - 签名:
F0:FD:6C:5B:41:0F:25:CB:25:C3:B5:33:46:C8:97:2F:AE:30:F8:EE:74:11:DF:91:04:80:AD:6B:2D:60:DB:83
智能家居关联请求由Google Home app (GHA)直接发起。如果您的应用限制调用方,并且之前仅允许 Google 搜索应用,则您必须将
com.google.android.apps.chromecast.app及其 SHA-256 证书添加到许可清单中,以便 App Flip 继续成功运行。private fun verifyFingerprint( expectedPackage: String, expectedFingerprints: List<String> ): Boolean { val callingPackage = callingActivity?.packageName ?: return false if (callingPackage != expectedPackage) return false return expectedFingerprints.any { hex -> val sha256Bytes = hex.split(":").map { it.toInt(16).toByte() }.toByteArray() packageManager.hasSigningCertificate( callingPackage, sha256Bytes, PackageManager.CERT_INPUT_SHA256 ) } }- 软件包名称:
从 intent 参数中提取客户端 ID,并验证客户端 ID 是否与预期值匹配。
private const val EXPECTED_CLIENT = "<client-id-from-actions-console>" private const val EXPECTED_PACKAGE = "com.google.android.apps.chromecast.app" // Original lineage certificate (3D:7A...) and active rotated // Play App Signing certificate (5A:AD...) private val EXPECTED_FINGERPRINTS = listOf( "3D:7A:12:23:01:9A:A3:9D:9E:A0:E3:43:6A:B7:C0:89:6B:FB:4F:B6:79:F4:DE:5F:E7:C2:3F:32:6C:8F:99:4A", "5A:AD:2B:EE:6D:B9:5D:17:E0:5A:08:D7:D1:E6:4C:10:A1:51:18:79:15:44:83:91:6B:6A:E6:C7:FD:9C:B0:C6" ) ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val clientId = intent.getStringExtra("CLIENT_ID") if (clientId == EXPECTED_CLIENT && verifyFingerprint(EXPECTED_PACKAGE, EXPECTED_FINGERPRINTS)) { // ...authorize the user... } }授权成功后,将生成的授权代码返回给 Google。
// Successful result val data = Intent().apply { putExtra("AUTHORIZATION_CODE", authCode) } setResult(Activity.RESULT_OK, data) finish()如果发生错误,则返回错误结果。
// Error result val error = Intent().apply { putExtra("ERROR_TYPE", 1) putExtra("ERROR_CODE", 1) putExtra("ERROR_DESCRIPTION", "Invalid Request") } setResult(-2, error) finish()
启动 intent 的内容
用于启动应用的 Android intent 包含以下字段:
CLIENT_ID(String):在您的应用下注册的 Googleclient_id。SCOPE(String[]):请求的范围列表。REDIRECT_URI(String):重定向网址。
响应数据的内容
返回到 Google 应用的数据是通过调用 setResult() 在您的应用中设置的。
此类数据包括:
AUTHORIZATION_CODE(String):授权代码值。resultCode(int):传达流程的成功或失败,并采用以下值之一:Activity.RESULT_OK:表示成功;系统会返回授权代码。Activity.RESULT_CANCELLED:可恢复的错误。表示用户已取消该流程。在这种情况下,Google 应用会尝试使用您的授权网址再次进行账号关联。-2:表示发生了错误。下面介绍了不同类型的错误。
ERROR_TYPE(int):错误的类型,采用以下值之一:1:可恢复的错误:Google 应用将尝试使用授权网址进行账号关联。2:不可恢复的错误:Google 应用中止账号关联。3:请求参数无效或缺失。
ERROR_CODE(int):表示错误性质的整数。如需了解每个错误代码的含义,请参阅错误代码表。ERROR_DESCRIPTION(String,可选):描述错误的人类可读状态消息。
当 resultCode == Activity.RESULT_OK 时,AUTHORIZATION_CODE 应有值。在所有其他情况下,AUTHORIZATION_CODE 的值需要为空。如果 resultCode == -2,则应填充 ERROR_TYPE 值。
错误代码表
下表显示了不同的错误代码,以及每个错误是可恢复还是不可恢复的错误:
| 错误代码 | 含义 | 可恢复 | 不可恢复 |
|---|---|---|---|
1 |
INVALID_REQUEST |
✔ | |
2 |
NO_INTERNET_CONNECTION |
✔ | |
3 |
OFFLINE_MODE_ACTIVE |
✔ | |
4 |
CONNECTION_TIMEOUT |
✔ | |
5 |
INTERNAL_ERROR |
✔ | |
6 |
AUTHENTICATION_SERVICE_UNAVAILABLE |
✔ | |
8 |
CLIENT_VERIFICATION_FAILED |
✔ | |
9 |
INVALID_CLIENT |
✔ | |
10 |
INVALID_APP_ID |
✔ | |
11 |
INVALID_REQUEST |
✔ | |
12 |
AUTHENTICATION_SERVICE_UNKNOWN_ERROR |
✔ | |
13 |
AUTHENTICATION_DENIED_BY_USER |
✔ | |
14 |
CANCELLED_BY_USER |
✔ | |
15 |
FAILURE_OTHER |
✔ | |
16 |
USER_AUTHENTICATION_FAILED |
✔ |
对于所有错误代码,您都必须通过 setResult 返回错误结果,以确保触发适当的后备。
在设备上测试App Flip
现在,你已在控制台和应用中创建了一个云到云集成并配置了 App Flip,接下来可以在移动设备上测试 App Flip。您可以使用 Google Home 应用测试 App Flip。
如需从 Google Home 应用测试 App Flip,请按以下步骤操作:
- 前往开发者控制台,然后选择您的项目。
- 前往云到云 > 测试。
- 在 Google Home 应用中触发账号关联流程:
- 打开 Google Home app (GHA)。
- 点击 + 按钮。
- 点击设置设备。
- 点击有已设置好的设备?
- 从提供商列表中选择您的云端到云端集成。它在列表中将带有“[test]”前缀。从列表中选择 [test] 集成后,就应该会打开您的应用。
- 验证您的应用是否已启动并开始测试授权流程。