OAuth 2.0“设备流”扩展在具有 Internet 连接但没有浏览器或没有简单的文本输入方法的设备上启用 OAuth。如果您曾在 Apple TV 等设备上登录过 YouTube 帐户,那么您已经遇到过此工作流程。Google 参与了此扩展的开发,并且也是生产中的早期实施者。
此流程也出现在智能电视、媒体控制台、相框、打印机或硬件视频编码器等设备上。在此流程中,设备指示用户在智能手机或计算机等辅助设备上打开 URL 以完成授权。用户的两个设备之间不需要通信通道。
当您开始在设备(例如这个硬件视频编码器)上登录时,设备会与 Google 对话以获取设备代码,如下所示。
接下来,我们看到设备随后向您显示代码以及 URL。
登录 Google 帐户后访问该 URL 会显示一个界面,提示您输入设备上显示的代码。
输入代码并单击“下一步”后,您将看到标准的 OAuth 授权提示,它描述了应用程序请求的范围,如下所示。
一旦您允许该请求,Google 就会显示一条消息,提示您返回到您的设备,如下所示。
几秒钟后,设备完成运行,您已登录。
总的来说,这是一次非常轻松的体验。由于您可以使用想要打开 URL 的任何设备,因此您可以使用您可能已经登录到授权服务器的主要计算机或电话。这也适用于无需在设备上输入数据的情况!无需在笨重的小键盘上输入密码或代码。
让我们来看看设备完成这项工作所需的条件。
首先,设备向授权服务器发出请求以请求设备代码,使用其客户端 ID 标识自己,并在需要时请求一个或多个范围。
POST /token HTTP/1.1
Host: authorization-server.com
Content-type: application/x-www-form-urlencoded
client_id=a17c21ed
授权服务器以包含设备代码、用户将输入的代码、用户应访问的 URL 和轮询间隔的 JSON 负载进行响应
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"device_code": "NGU5OWFiNjQ5YmQwNGY3YTdmZTEyNzQ3YzQ1YSA",
"user_code": "BDWP-HQPK",
"verification_uri": "https://authorization-server.com/device",
"interval": 5,
"expires_in": 1800
}
设备在其显示屏上向用户显示verification_uri
和 ,指示用户在该 URL 输入代码。user_code
当设备等待用户在他们自己的计算机或手机上完成授权流程时,设备同时开始轮询令牌端点以请求访问令牌。
设备以device_code
指定的速率发出 POST 请求interval
。设备应继续请求访问令牌,直到返回除响应以外的响应(authorization_pending
用户授予或拒绝请求或设备代码过期)。
POST /token HTTP/1.1
Host: authorization-server.com
Content-type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:device_code&
client_id=a17c21ed&
device_code=NGU5OWFiNjQ5YmQwNGY3YTdmZTEyNzQ3YzQ1YSA
授权服务器将回复错误或访问令牌。Device Flow 规范定义了两个额外的错误代码,超出了 OAuth 2.0 核心中定义的内容,authorization_pending
以及slow_down
.
如果设备轮询过于频繁,授权服务器将返回错误slow_down
。
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "slow_down"
}
如果用户尚未允许或拒绝请求,授权服务器将返回错误authorization_pending
。
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "authorization_pending"
}
如果用户拒绝请求,授权服务器将返回错误access_denied
。
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "access_denied"
}
如果设备代码已过期,授权服务器将返回错误expired_token
。设备可以立即请求新的设备代码。
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "expired_token"
}
最后,如果用户允许该请求,则授权服务器会像往常一样发出访问令牌并返回标准访问令牌响应。
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "AYjcyMzY3ZDhiNmJkNTY",
"refresh_token": "RjY2NjM5NzA2OWJjuE7c",
"token_type": "Bearer",
"expires": 3600,
"scope": "create"
}