您可以让用户在输入功能有限的设备(例如联网电视)上使用他们的 Google 帐户登录您的应用。
该应用程序向用户显示一个短代码和登录 URL。然后,用户在 Web 浏览器中打开登录 URL,输入代码,并授予应用访问用户登录信息的权限。最后,应用程序收到确认并且用户登录。
要使用此登录流程,应用程序必须在满足以下条件的设备上运行:
- 设备必须能够显示 40 个字符的 URL 和 15 个字符的用户代码,以及对用户的说明。
- 设备必须连接到 Internet。
获取客户端 ID 和客户端密码
您的应用需要 OAuth 2.0 客户端 ID 和客户端密码才能向 Google 的登录端点发出请求。
要查找项目的客户端 ID 和客户端密码,请执行以下操作:
- 选择现有的 OAuth 2.0 凭证或打开凭证页面。
- 如果您还没有这样做,请单击Create credentials > OAuth client ID 创建项目的 OAuth 2.0 凭证,并提供创建凭证所需的信息。
- 在OAuth 2.0 客户端 ID部分中查找客户端 ID。有关详细信息,请单击客户端 ID。
如果您要创建新的客户端 ID,请选择电视和受限输入设备应用程序类型。
获取用户代码和验证 URL
用户请求使用 Google 帐户登录后,您可以通过向 OAuth 2.0 设备端点https://oauth2.googleapis.com/device/code
发送 HTTP POST 请求来获取用户代码和验证 URL。在请求中包含您的客户端 ID 和您需要的范围列表。如果您只想使用他们的 Google 帐户登录用户,请仅请求profile
和email
范围;或者,如果您想请求代表用户调用受支持 API的权限,请在profile
和email
范围之外请求所需的范围。
以下是用户代码的示例请求:
POST /device/code HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=CLIENT_ID&scope=email%20profile
使用curl
:
curl -d "client_id=CLIENT_ID&scope=email profile" https://oauth2.googleapis.com/device/code
响应作为 JSON 对象返回:
{
"device_code" : "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
"user_code" : "GQVQ-JKEC",
"verification_url" : "https://www.google.com/device",
"expires_in" : 1800,
"interval" : 5
}
您的应用会向用户显示user_code
和verification_url
值,同时按指定的interval
轮询登录端点,直到用户登录或expires_in
指定的时间过去。
显示用户代码和验证 URL
从设备端点收到用户代码和验证 URL 后,显示它们并指示用户打开 URL 并输入用户代码。
user_code
verification_url
值可能会发生变化。以可以处理以下限制的方式设计您的 UI:
-
user_code
必须显示在足以处理 15 个W
大小字符的字段中。 -
verification_url
必须显示在足以处理 40 个字符长的 URL 字符串的字段中。
两个字符串都可以包含 US-ASCII 字符集中的任何可打印字符。
当您显示user_code
字符串时,请不要以任何方式修改字符串(例如更改大小写或插入其他格式字符),因为如果将来代码格式发生更改,您的应用程序可能会中断。
如果您愿意,您可以通过从 URL 中剥离方案来修改verification_url
字符串以进行显示。如果这样做,请确保您的应用程序可以同时处理“http”和“https”变体。不要以其他方式修改verification_url
字符串。
当用户导航到验证 URL 时,他们会看到类似于以下内容的页面:
用户输入用户代码后,Google 登录站点会显示类似于以下内容的同意屏幕:
如果用户单击Allow ,那么您的应用可以获取一个 ID 令牌来识别用户,一个访问令牌来调用 Google API,以及一个刷新令牌来获取新令牌。
获取 ID 令牌和刷新令牌
在您的应用显示用户代码和验证 URL 后,开始使用您从设备端点收到的设备代码轮询令牌端点 ( https://oauth2.googleapis.com/token
)。以interval
值指定的间隔(以秒为单位)轮询令牌端点。
以下是一个示例请求:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=CLIENT_ID&client_secret=CLIENT_SECRET&code=DEVICE_CODE&grant_type=http://oauth.net/grant_type/device/1.0
使用curl
:
curl -d "client_id=CLIENT_ID&client_secret=CLIENT_SECRET&code=DEVICE_CODE&grant_type=http://oauth.net/grant_type/device/1.0" https://oauth2.googleapis.com/token
如果用户尚未批准该请求,则响应如下:
{
"error" : "authorization_pending"
}
您的应用应以不超过interval
值的速率重复这些请求。如果您的应用轮询过快,响应如下:
{
"error" : "slow_down"
}
用户登录并授予您的应用访问您请求的范围后,对应用的下一个请求的响应包括一个 ID 令牌、一个访问令牌和一个刷新令牌:
{
"access_token" : "ya29.AHES6ZSuY8f6WFLswSv0HZLP2J4cCvFSj-8GiZM0Pr6cgXU",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/551G1yXUqgkDGnkfFk6ZbjMMMDIMxo3JFc8lY8CAR-Q",
"id_token": "eyJhbGciOiJSUzI..."
}
收到此响应后,您的应用程序可以解码 ID 令牌以获取有关已登录用户的基本配置文件信息,或将 ID 令牌发送到您的应用程序的后端服务器以安全地通过服务器进行身份验证。此外,您的应用可以使用访问令牌来调用用户授权的 Google API 。
ID 和访问令牌的生命周期有限。要让用户在令牌的生命周期之外登录,请存储刷新令牌并使用它来请求新令牌。
从 ID 令牌中获取用户配置文件信息
您可以通过使用任何JWT 解码库对 ID 令牌进行解码来获取有关已登录用户的个人资料信息。例如,使用 Auth0 jwt-decode JavaScript 库:
var user_profile = jwt_decode(id_token); // The "sub" field is available on all ID tokens. This value is unique for each // Google account and can be used to identify the user. (But do not send this // value to your server; instead, send the whole ID token so its authenticity // can be verified.) var user_id = user_profile["sub"]; // These values are available when you request the "profile" and "email" scopes. var user_email = user_profile["email"]; var email_verified = user_profile["email_verified"]; var user_name = user_profile["name"]; var user_photo_url = user_profile["picture"]; var user_given_name = user_profile["given_name"]; var user_family_name = user_profile["family_name"]; var user_locale = user_profile["locale"];
更多信息
- 要使用户在 ID 令牌的生命周期后仍保持登录状态,请参阅刷新访问令牌。
- 如果您需要使用后端服务器进行身份验证,请参阅使用后端服务器进行身份验证以获取有关安全执行此操作的信息。