通过 Google 帐号关联,Google 帐号持有人可以快速、无缝、安全地连接到您的服务并与 Google 共享数据。
“关联的帐号登录”功能可让已将 Google 帐号关联到您的服务的用户启用一键登录 Google。这可以改善用户的体验,因为他们只需点击一下即可登录,而无需重新输入用户名和密码。这也减少了用户使用您的服务创建重复帐号的机会。
要求
如需实现关联的帐号登录,您必须满足以下要求:
- 您的 Google 帐号 OAuth 关联实现支持 OAuth 2.0 授权代码流程。您的 OAuth 实现必须包含以下端点:
- 授权端点来处理授权请求。
- token endpoint 处理访问令牌和刷新令牌的请求。
- userinfo 端点,以检索在关联的帐号登录过程中向用户显示的已关联用户的基本帐号信息。
- 您拥有 Android 应用。
工作原理
前提条件 :用户之前已将他们的 Google 帐号与您的服务帐号相关联。
- 您可以在一键登录流程中选择显示关联的帐号。
- 用户会看到“一键登录”提示,以及使用关联的帐号登录服务的选项。
- 如果用户选择继续使用关联的帐号,Google 会向您的令牌端点发送请求,以保存授权代码。该请求包含您的服务颁发的用户访问令牌和 Google 授权代码。
- 您可以使用 Google 授权代码换取包含用户 Google 帐号相关信息的 Google ID 令牌。
- 在流程完成后,您的应用还会收到 ID 令牌,您可以将此 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
是否已授予client_id
标识的 Google。 - 如果请求有效且授权代码成功交换到 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 帐号相关信息的 Google ID 令牌。
要使用 Google ID 令牌交换授权代码,请调用 https://oauth2.googleapis.com/token
端点并设置以下参数:
请求字段 | |
---|---|
client_id |
必需:从 API 控制台“凭据”页面获取的客户端 ID。这通常是名称为 New Actions on Google App 的凭据 |
client_secret |
必填 从 API 控制台的“凭据”页面获取的客户端密钥 |
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 令牌响应
Validate and decode the JWT assertion
You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.
When decoded, the JWT assertion looks like the following example:
{ "sub": "1234567890", // The unique ID of the user's Google Account "iss": "https://accounts.google.com", // The assertion's issuer "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID "iat": 233366400, // Unix timestamp of the assertion's creation time "exp": 233370000, // Unix timestamp of the assertion's expiration time "name": "Jan Jansen", "given_name": "Jan", "family_name": "Jansen", "email": "jan@gmail.com", // If present, the user's email address "email_verified": true, // true, if Google has verified the email address "hd": "example.com", // If present, the host domain of the user's GSuite email address // If present, a URL to user's profile picture "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ", "locale": "en_US" // User's locale, from browser or phone settings }
In addition to verifying the token's signature, verify that the assertion's
issuer (iss
field) is https://accounts.google.com
, that the audience
(aud
field) is your assigned client ID, and that the token has not expired
(exp
field).
Using the email
, email_verified
and hd
fields you can determine if
Google hosts and is authoritative for an email address. In cases where Google is
authoritative the user is currently known to be the legitimate account owner
and you may skip password or other challenges methods. Otherwise, these methods
can be used to verify the account prior to linking.
Cases where Google is authoritative:
email
has a@gmail.com
suffix, this is a Gmail account.email_verified
is true andhd
is set, this is a G Suite account.
Users may register for Google Accounts without using Gmail or G Suite. When
email
does not contain a @gmail.com
suffix and hd
is absent Google is not
authoritative and password or other challenge methods are recommended to verify
the user. email_verfied
can also be true as Google initially verified the
user when the Google account was created, however ownership of the third party
email account may have since changed.