电视和设备的Google登录

您可以让用户在输入功能受限的设备(例如连接互联网的电视)上使用其Google帐户登录您的应用。

该应用程序向用户显示一个简短的代码和登录URL。然后,用户在Web浏览器中打开登录URL,输入代码,并授予应用访问用户登录信息的权限。最终,该应用收到确认,并且用户已登录。

要使用此登录流程,该应用必须在满足以下条件的设备上运行:

  • 该设备必须能够显示40个字符的URL和15个字符的用户代码,以及对用户的指示。
  • 该设备必须连接到Internet。

获取客户ID和客户机密

您的应用需要OAuth 2.0客户端ID和客户端密码,才能向Google的登录端点发出请求。

要找到您项目的客户ID和客户机密,请执行以下操作:

  1. 选择现有的OAuth 2.0凭据或打开“凭据”页面
  2. 如果尚未执行此操作,请通过单击创建凭据> OAuth客户端ID并提供创建凭据所需的信息来创建项目的OAuth 2.0凭据。
  3. OAuth 2.0客户端ID部分中查找客户端ID 。有关详细信息,请单击客户端ID。

如果要创建新的客户端ID,请选择“电视和受限输入设备”应用程序类型。

获取用户代码和验证URL

用户请求使用Google帐户登录后,您可以通过向OAuth 2.0设备端点https://oauth2.googleapis.com/device/code发送HTTP POST请求来获取用户代码和验证URL。在请求中包括您的客户ID和所需范围的列表。如果您只想使用其Google帐户登录用户,则仅请求profileemail范围;或者,如果您想请求代表用户调用受支持的API的权限,除了profileemail范围之外,还请求所需的范围。

以下是请求用户代码的示例:

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_codeverification_url值,并同时以指定的interval轮询登录端点,直到用户登录或通过expires_in指定的interval为止。

显示用户代码和验证URL

从设备端点收到用户代码和验证URL后,显示它们并指示用户打开URL并输入用户代码。

verification_urluser_code的值可能会发生变化。以可以处理以下限制的方式设计用户界面:

  • user_code必须显示在足够宽的字段中,以处理15 W大小的字符。
  • verification_url必须显示在足够宽的字段中,以处理40个字符长的URL字符串。

这两个字符串都可以包含US-ASCII字符集中的任何可打印字符。

显示user_code字符串时,请勿以任何方式修改该字符串(例如更改大小写或插入其他格式字符),因为如果将来代码格式更改,您的应用程序可能会中断。

您可以通过从URL剥离方案来修改verification_url字符串,以供显示(如果您选择)。如果这样做,请确保您的应用程序可以同时处理“ http”和“ https”变体。否则,请勿修改verification_url字符串。

当用户导航到验证URL时,他们会看到类似于以下内容的页面:

通过输入代码连接设备

用户输入用户代码后,Google登录网站将显示一个类似于以下内容的同意屏幕:

设备客户端的同意屏幕示例

如果用户单击允许,则您的应用可以获取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"];

更多信息