本系列文之後也会置於个人网站
+----------+ +----------------+
| |>---(A)-- Client Identifier --->| |
| | | |
| |<---(B)-- Device Code, ---<| |
| | User Code, | |
| Device | & Verification URI | |
| Client | | |
| | [polling] | |
| |>---(E)-- Device Code --->| |
| | & Client Identifier | |
| | | Authorization |
| |<---(F)-- Access Token ---<| Server |
+----------+ (& Optional Refresh Token) | |
v | |
: | |
(C) User Code & Verification URI | |
: | |
v | |
+----------+ | |
| End User | | |
| at |<---(D)-- End user reviews --->| |
| Browser | authorization request | |
+----------+ +----------------+
Figure 1: Device Authorization Flow
The device authorization flow illustrated in Figure 1 includes the
following steps:
(A) The client requests access from the authorization server and
includes its client identifier in the request.
(B) The authorization server issues a device code and an end-user
code and provides the end-user verification URI.
(C) The client instructs the end user to use a user agent on another
device and visit the provided end-user verification URI. The
client provides the user with the end-user code to enter in
order to review the authorization request.
Device Code Flow这个与前面几个特别不一样。在之前,以往都是从登入开始,然後跳转页面回到App(Client)。也就是通常先有的是前端通讯,然後才是後端通信。
这次不太同,开始不再是由资源拥有者发起,更像是由客户端开始。甚至登入的方法与客户端还没有特别强烈的关联。大致流程说明如下:
device_code
和user_code
。user_code
交给资源拥有者。user_code
进行授权。device_code
询问授权服务器是某有人授权。在这里device_code
有点更像是传统的session
。user_code
更像是之前的特殊密码。
硬要比喻的话,就像是有一个充满智慧的门,就先叫做「魔门」吧!这个魔门不但聪明还会识别人脸。它知道未来有一天,一定会有一个人来开启它这扇门,但他不知道是谁。於是他把一段咒语--「魔门阿!魔门!谁是世界上最安全的锁」--告诉管家。如果有一天有一个人将这个咒语告诉了管家,那就请管家将这个人的脸纪录下来,并告诉魔门。当这个人走到魔门前面的时候,魔门就认得这张人脸,也就会自动开门了。
怕有人不知道。「魔镜」的故事听过吧XD
虽然这个比喻并不完全匹配,但是这里的「魔镜」有点像是客户端;「管家」仍然是授权服务器。与之前几个流程相比,有点像是反过来走。
example-device-app
由於OAuth Playground和OAuth.tools都不太能很好的用来理解这个模式。所以这一个会分成两个部分介绍,除了实际走走上面提到的流程,还会在实际开发一个简易的客户端。如此,希望能够使各位能够更明白Device Code Flow。
那麽就先来再建立一个客户端。
尽管用之前的「oauth_tools」或是调整「my-quick-start-app」也可以。不过还是从头来一遍吧!
example-device-app
http://localhost:4200/
虽然这次Root URL并不是很重要,但还是填上与「my-quick-start-app」相同的值吧!
然後注意这次的Access Type需要选择confidential
并且将Oauth 2.0 Device Authorization Grant啓用。
然後先将 Credentials > Secret 记下来。
这麽一来前置工作就算是准备好了。
device_code
和user_code
这次要用HTTP POST的方法打http://localhost:8080/auth/realms/quick-start/device
这个端点。
这次需要配合 Client Credentials 模式。所以不但要给client_id
,也需要client_secret
。client_secret
填入刚刚所记下来的secret
。
example-device-app
<方才记录下来的secret>
在送出request後会得到一些资讯。
{
"device_code": "boTQ6vd49RXTOYOb7dwXBCpHYskzOjXvDPjkXxniMN0",
"user_code": "HZYO-ROXJ",
"verification_uri": "http://localhost:8080/auth/realms/quick-start/device",
"verification_uri_complete": "http://localhost:8080/auth/realms/quick-start/device?user_code=HZYO-ROXJ",
"expires_in": 600,
"interval": 5
}
其中最重要的是device_code
、user_code
和verification_uri
。
到这边算是初步完成了,但你可以先透过token_endpoint
,也就是http://localhost:8080/auth/realms/quick-start/protocol/openid-connect/token
这个端点确定一下。
除了需要给与device_code以外,还需要将grant_type改成urn:ietf:params:oauth:grant-type:device_code
。
urn:ietf:params:oauth:grant-type:device_code
<方才取得的device_code>
现在,你应该会得到仍未有人登入授权。
魔门 真是孤独阿~
{
"error": "authorization_pending",
"error_description": "The authorization request is still pending"
}
接着,同样透过刚刚知道的端点 verification_uri 登入。浏览器开啓 http://localhost:8080/auth/realms/quick-start/device ,并输入同样刚才得到的user_code:
或者是一个特殊的端点http://localhost:8080/auth/realms/quick-start/device?user_code=<user_code>
。但总之登入後的是一个授权画面。
在看下Yes允许授权後,提示的是登入成功,我们可以回到我们的应用。
同样在尝试取得一次存取权杖看看:
urn:ietf:params:oauth:grant-type:device_code
<方才取得的device_code>
这次我们就可以取得存取权杖了~
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ4VXh6WGR4UWpFNDNIZGdYbXJkUjBQZWxXN1ZoZWowbGRkR2NhN0VubXpZIn0.eyJleHAiOjE2MzI1Nzg5NTQsImlhdCI6MTYzMjU3ODY1NCwiYXV0aF90aW1lIjoxNjMyNTc3NTIxLCJqdGkiOiI5YTBhYTdkZi02NmEyLTRlMDgtYmZmNS05MjU2NDZlYmM1MTkiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvcXVpY2stc3RhcnQiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMzQ1YjFiY2EtOTgwNS00YjRiLWEwZjgtZGEyYzcwMTc2YzU5IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiZXhhbXBsZS1kZXZpY2UtYXBwIiwic2Vzc2lvbl9zdGF0ZSI6ImFmODhlZmZiLTVmNDgtNDgxZi04YWI2LTQ5MGRhMjY2YzY1ZCIsImFjciI6IjAiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo0MjAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXF1aWNrLXN0YXJ0Iiwib2ZmbGluZV9hY2Nlc3MiLCJxdWljay1zdGFydC1leGFtcGxlLXJvbGUxIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJzaWQiOiJhZjg4ZWZmYi01ZjQ4LTQ4MWYtOGFiNi00OTBkYTI2NmM2NWQiLCJ3ZWJzaXRlIjoiaHR0cHM6Ly9ib2IuaWQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ2VuZGVyIjoibWFuIiwibmFtZSI6IkJvYiBMZWUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJib2IiLCJnaXZlbl9uYW1lIjoiQm9iIiwiZmFtaWx5X25hbWUiOiJMZWUiLCJlbWFpbCI6ImJvYkBmYWtlLmVtYWlsIn0.aPYPiG9icNnrxmmRUPoN_rf2eLhkprK7haXD9M6CpGRAHnjyzOkH1H2an3Au2I4LgFX7fdO95E5mF7NZ4gw-5SFe9Wof3Toe8araIQepurJXMd9Vx9Y6cO-htha796rkpUq2XNkcBLRHl9bN2zN3-2VM1X1pBqQPtDPeGckkp_2KH8u8n9UPxdq_lD-FZ_3-YzQav1RTs81QkxEBTn8Un7mzgRjdsmIkEJKYQqnhg86Xkw_bAGz-F-nDoj1XtHqjSIk_1EZ9brcgi05us-9ZL0tBViycQRCXEgJjq555omxh1XgjjuC_KPzA3y7hTTE75ZvO-3rc0sVy1DC-1AEtbg",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0NjUwNDBkYi1lNGJkLTRiYTYtOWM2Ny02ZWYxZGJmMmUxOWYifQ.eyJleHAiOjE2MzI1ODA0NTQsImlhdCI6MTYzMjU3ODY1NCwianRpIjoiZGI3NTBjOTMtODg3Mi00YmUxLTk3YWUtMmU2MTMxNzNjMDU2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3F1aWNrLXN0YXJ0IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3F1aWNrLXN0YXJ0Iiwic3ViIjoiMzQ1YjFiY2EtOTgwNS00YjRiLWEwZjgtZGEyYzcwMTc2YzU5IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImV4YW1wbGUtZGV2aWNlLWFwcCIsInNlc3Npb25fc3RhdGUiOiJhZjg4ZWZmYi01ZjQ4LTQ4MWYtOGFiNi00OTBkYTI2NmM2NWQiLCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJzaWQiOiJhZjg4ZWZmYi01ZjQ4LTQ4MWYtOGFiNi00OTBkYTI2NmM2NWQifQ.1NGocwCZbpT-OjKnVj420Vql1_C3iwcZavuwJEk2sk0",
"token_type": "Bearer",
"not-before-policy": 1631743594,
"session_state": "af88effb-5f48-481f-8ab6-490da266c65d",
"scope": "email profile"
}
>>: [DAY 20]用bot打出色色柴犬counter牌(更新句子相似度判断)
朋友送了一组键盘滑鼠.Logitech 键盘yr0009 & 滑鼠M215 想要滑鼠放家里用...
回到MNIST手写数字辨识的单元,前面已经完成了模型的建立及训练,也学会如何印出和判读训练过程,那麽...
怎麽样确定这个人就对的那个人?前一篇有提到面试官可以怎麽提问技术题,那麽要确认应徵者的人格特质可以从...
has_many 的设定 class_name 可以变更关联的类别名称,例如以下新增了paid_at...
二元搜寻BigO(log n) 相较於线性搜寻时间复杂度实在好太多 必须是被排序好的 由於每次对半砍...