Google 账号关联使 Google 账号持有者能够快速、无缝且安全地连接到您的服务并与 Google 共享数据。
关联账号登录为已将 Google 账号与您的服务关联的用户启用了 通过 Google 一键登录功能。这提高了用户体验,因为用户只需点击一次即可登录,无需重新输入用户名和密码。它还降低了用户在您的服务上创建重复账号的可能性。
要求
要实现关联账号登录,您必须满足以下要求:
- 您已有支持 OAuth 2.0 授权代码流程的 Google 账号 OAuth 关联实现。您的 OAuth 实现必须包含以下端点:
- 授权端点,用于处理授权请求。
- 令牌端点,用于处理访问令牌和刷新令牌的请求。
- userinfo 端点,用于检索关联用户的基本账号信息,这些信息会在关联账号登录过程中向用户显示。
- 您拥有一个 Android 应用。
工作原理
前提条件:用户之前已将其 Google 账号与您服务上的账号关联。
- 您选择在 One Tap 登录流程中显示关联账号。
- 系统会向用户显示 One Tap 登录提示,用户可以选择使用其关联账号登录您的服务。
- 如果用户选择继续使用关联账号,Google 会向您的令牌端点发送请求,以保存授权代码。请求中包含您的服务颁发给用户的访问令牌和 Google 授权代码。
- 您将 Google 授权代码换取 Google ID 令牌,该令牌包含有关用户 Google 账号的信息。
- 您的应用在此流程完成后也会收到一个 ID 令牌,您将此令牌与服务器收到的 ID 令牌中的用户标识符进行匹配,以便将用户登录到您的应用中。
在您的 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