关联账号登录

Google 账号关联使 Google 账号持有者能够快速、无缝且安全地连接到您的服务并与 Google 共享数据。

关联账号登录为已将 Google 账号与您的服务关联的用户启用了 通过 Google 一键登录功能。这提高了用户体验,因为用户只需点击一次即可登录,无需重新输入用户名和密码。它还降低了用户在您的服务上创建重复账号的可能性。

要求

要实现关联账号登录,您必须满足以下要求:

  • 您已有支持 OAuth 2.0 授权代码流程的 Google 账号 OAuth 关联实现。您的 OAuth 实现必须包含以下端点:
    • 授权端点,用于处理授权请求。
    • 令牌端点,用于处理访问令牌和刷新令牌的请求。
    • userinfo 端点,用于检索关联用户的基本账号信息,这些信息会在关联账号登录过程中向用户显示。
  • 您拥有一个 Android 应用。

工作原理

前提条件:用户之前已将其 Google 账号与您服务上的账号关联。

  1. 您选择在 One Tap 登录流程中显示关联账号。
  2. 系统会向用户显示 One Tap 登录提示,用户可以选择使用其关联账号登录您的服务。
  3. 如果用户选择继续使用关联账号,Google 会向您的令牌端点发送请求,以保存授权代码。请求中包含您的服务颁发给用户的访问令牌和 Google 授权代码。
  4. 您将 Google 授权代码换取 Google ID 令牌,该令牌包含有关用户 Google 账号的信息。
  5. 您的应用在此流程完成后也会收到一个 ID 令牌,您将此令牌与服务器收到的 ID 令牌中的用户标识符进行匹配,以便将用户登录到您的应用中。
Linked Account Sign-In.
图 1. 关联账号登录流程。如果用户设备上已登录多个账号,用户可能会看到一个账号选择器,只有在选择了关联账号后才会进入关联账号登录界面。

在您的 Android 应用中实现关联账号登录

要在您的 Android 应用中支持关联账号登录,请遵循Android 实现指南中的说明。

处理来自 Google 的授权代码请求

Google 会向您的令牌端点发起 POST 请求,以保存授权代码,您将该代码换取用户的 ID 令牌。请求中包含用户的访问令牌和 Google 颁发的 OAuth2 授权代码。

在保存授权代码之前,您必须验证访问令牌是否由您授予 Google,可通过 client_id 识别。

HTTP 请求

请求示例

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

code=GOOGLE_AUTHORIZATION_CODE
&grant_type=urn:ietf:params:oauth:grant-type:reciprocal
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&access_token=ACCESS_TOKEN

您的令牌交换端点必须能够处理以下请求参数:

令牌端点参数
code 必需 Google OAuth2 授权代码
client_id 必需 您向 Google 颁发的客户端 ID
client_secret 必需 您向 Google 颁发的客户端密钥
access_token 必需 您向 Google 颁发的访问令牌。您将使用此令牌获取用户上下文。
grant_type 必需 值必须设置为 urn:ietf:params:oauth:grant-type:reciprocal

您的令牌交换端点应按如下方式响应 POST 请求:

  • 验证 access_token 是否已授予 Google,可通过 client_id 识别。
  • 如果请求有效且授权代码成功换取了 Google ID 令牌,则响应 HTTP 200 (OK);如果请求无效,则响应 HTTP 错误代码。

HTTP 响应

成功

返回 HTTP 状态码 200 OK

成功响应示例
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{}

错误

如果 HTTP 请求无效,请使用以下 HTTP 错误代码之一进行响应:

HTTP 状态码 正文 说明
400 {"error": "invalid_request"} 请求缺少参数,服务器无法继续处理请求。如果请求包含不受支持的参数或重复参数,也可能返回此错误。
401 {"error": "invalid_request"} 客户端身份验证失败,例如请求包含无效的客户端 ID 或密钥。
401 {"error": "invalid_token"}

在响应头中包含“WWW-Authentication: Bearer”身份验证质询

合作伙伴访问令牌无效。
403 {"error": "insufficient_permission"}

在响应头中包含“WWW-Authentication: Bearer”身份验证质询

合作伙伴访问令牌不包含执行互惠 OAuth 所需的范围。
500 {"error": "internal_error"} 服务器错误

错误响应应包含以下字段:

错误响应字段
error 必需 错误字符串
error_description 人类可读的错误说明
error_uri 提供有关错误的更多详细信息的 URI
错误 400 响应示例
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "error": "invalid_request",
  "error_description": "Request was missing the 'access_token' parameter."
}

将授权代码换取 ID 令牌

您需要将收到的授权代码换取 Google ID 令牌,该令牌包含有关用户 Google 账号的信息。

要将授权代码换取 Google ID 令牌,请调用 https://oauth2.googleapis.com/token 端点并设置以下参数:

请求字段
client_id 必需 从 API Console 凭据页面获取的客户端 ID。这通常是名称为 New Actions on Google App 的凭据。
client_secret 必需 从 API Console 凭据页面获取的客户端密钥。
code 必需 初始请求中发送的授权代码。
grant_type 必需 按照 OAuth 2.0 规范定义,此字段的值必须设置为 authorization_code
请求示例
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=GOOGLE_AUTHORIZATION_CODE
&grant_type=authorization_code
&client_id=GOOGLE_CLIENT_ID
&client_secret=GOOGLE_CLIENT_SECRET

Google 通过返回一个 JSON 对象来响应此请求,该对象包含一个短期访问令牌和一个刷新令牌。

响应包含以下字段:

响应字段
access_token Google 颁发的访问令牌,您的应用将其发送以授权 Google API 请求。
id_token ID 令牌包含用户的 Google 账号信息。验证响应部分包含有关如何解码和验证 ID 令牌响应的详细信息。
expires_in 访问令牌的剩余生命周期(以秒为单位)。
refresh_token 您可以用来获取新的访问令牌的令牌。刷新令牌在用户撤销访问权限之前一直有效。
scope 对于关联账号登录用例,此字段的值始终设置为 openid。
token_type 返回的令牌类型。目前,此字段的值始终设置为 Bearer
响应示例
HTTP/1.1 200 OK
Content-type: application/json; charset=utf-8

{
  "access_token": "Google-access-token",
  "id_token": "Google-ID-token",
  "expires_in": 3599,
  "token_type": "Bearer",
  "scope": "openid",
  "refresh_token": "Google-refresh-token"
}


POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=Google authorization code
&grant_type=authorization_code
&client_id=Google client id
&client_secret=Google client secret

验证 ID 令牌响应