本文為學(xué)習(xí)多篇OAuth 2.0文章后總結(jié)筏餐。
具體授權(quán)碼模式請看 阮一峰老師講解 OAuth 2.0 的四種方式
https://tools.ietf.org/html/rfc6749
https://www.ixigua.com/6841902954690118155
1. 授權(quán)碼 - authorization code
客戶端換取授權(quán)碼姨伤,客戶端調(diào)用服務(wù)端使用授權(quán)碼換token,客戶端調(diào)用服務(wù)端使用token訪問資源
必須要有服務(wù)端
- 授權(quán)碼模式是四種模式中最繁瑣也是最安全的一種模式。
- client_id 存儲在前端
- client_secret 存儲在服務(wù)器
- 支持refresh token
- 使用場景:第三方Web服務(wù)器端應(yīng)用與第三方原生App规惰,例如頭條微信授權(quán)登錄
授權(quán)碼請求
response_type:(必傳)此時為"code"
appid: (必傳)微信服務(wù)器下發(fā)的標(biāo)識第三方應(yīng)用的
client_id: (必傳)微信服務(wù)器下發(fā)的標(biāo)識第三方應(yīng)用的空厌,和appid根據(jù)要求可選
redirect_uri: (必傳)授權(quán)成功后的重定向地址
scope:(可選)標(biāo)識授權(quán)范圍
state:(推薦)第三方應(yīng)用提供的一個字符串,微信授權(quán)服務(wù)器會原樣返回
1.請求授權(quán)碼(示例)
GET /authorize?
response_type=code&
appid=wxe9199d568fe57fdd&
client_id=wxe9199d568fe57fdd&
state=wilson&
redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Foauth2&
scope=user,photo HTTP/1.1
2.授權(quán)碼根據(jù)重定向地址返回 (前端地址颖御?后臺api榄棵?)
HTTP/1.1 302 Found
Location: https://client.example.com/oauth2?code=SplxlOBeZQQYbYS6WxSbIA&state=wilson
3.拿到授權(quán)碼以后,在 后端服務(wù)潘拱,直接向 微信授權(quán)服務(wù)器 請求令牌
https://xeixin.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL
案例:https://www.toutiao.com/a6643594372862444040/
2. 授權(quán)碼 "隱藏式" - implicit
客戶端讓用戶登錄授權(quán)服務(wù)器換token疹鳄,客戶端使用token訪問資源(只有客戶端,沒有服務(wù)端)
- 支持refresh token
- 使用場景:為web瀏覽器應(yīng)用設(shè)計芦岂。一般簡化模式用于沒有服務(wù)器端的第三方單頁面應(yīng)用瘪弓,因?yàn)闆]有服務(wù)器端就無法使用授權(quán)碼模式。
https://b.com/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
3. 密碼式 - password
用戶在客戶端提交賬號密碼換token禽最,客戶端使用token訪問資源
- 不支持refresh token
- 使用場景:為遺留系統(tǒng)設(shè)計腺怯。這種模式十分簡單,但是卻意味著直接將用戶敏感信息泄漏給了client川无,因此這就說明這種模式只能用于client是我們自己開發(fā)的情況下呛占。因此密碼模式一般用于我們自己開發(fā)的,第一方原生App或第一方單頁面應(yīng)用懦趋。
https://oauth.b.com/token?
grant_type=password&
username=USERNAME&
password=PASSWORD&
client_id=CLIENT_ID
4. 客戶端憑證 - Client Credentials Grant
客戶端使用自己的標(biāo)識換token晾虑,客戶端使用token訪問資源
- 不支持refresh token
- 使用場景:為后臺api服務(wù)消費(fèi)者設(shè)計。一般用來提供給我們完全信任的服務(wù)器端服務(wù)愕够。
https://oauth.b.com/token?
grant_type=client_credentials&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
如何在移動App中使用OAuth 2.0走贪?
移動 App 可以分為兩類,一類是沒有 Server 端的 App 應(yīng)用惑芭,一類是有 Server 端的 App 應(yīng)用坠狡。
這兩類 App 在使用 OAuth 2.0 時的最大區(qū)別,在于獲取訪問令牌的方式:
- 如果有 Server 端遂跟,就建議通過 Server 端和授權(quán)服務(wù)做交互來換取訪問令牌逃沿;
- 如果沒有 Server 端婴渡,那么只能通過前端通信來跟授權(quán)服務(wù)做交互,比如隱式許可授權(quán)類型凯亮。當(dāng)然边臼,這種方式的安全性就降低了很多。也可以將一個“迷你”的 Web 服務(wù)器嵌入到 App 里面去假消,這樣就可以像 Web 應(yīng)用那樣來使用 OAuth 2.0 柠并。這樣的 App 通過監(jiān)聽運(yùn)行在 localhost 上的 Web 服務(wù)器 URI,就可以做到跟普通的 Web 應(yīng)用一樣的通信機(jī)制富拗。
這里介紹另外一種 PKCE 協(xié)議臼予,全稱是 Proof Key for Code Exchange by OAuth Public Clients。在下面的流程圖中啃沪,為了突出第三方軟件使用 PKCE 協(xié)議時與授權(quán)服務(wù)之間的通信過程粘拾,我省略了受保護(hù)資源服務(wù)和資源擁有者的角色:
首先,App 自己要生成一個隨機(jī)的创千、長度在 43~128 字符之間的缰雇、參數(shù)為 code_verifier 的字符串驗(yàn)證碼;接著追驴,我們再利用這個 code_verifier械哟,來生成一個被稱為“挑戰(zhàn)碼”的參數(shù)code_challenge。那怎么生成這個 code_challenge 的值呢氯檐?OAuth 2.0 規(guī)范里面給出了兩種方法戒良,就是看 code_challenge_method 這個參數(shù)的值:
- 一種 code_challenge_method=plain,此時 code_verifier 的值就是 code_challenge 的值冠摄;
- 另外一種 code_challenge_method=S256糯崎,就是將 code_verifier 值進(jìn)行 ASCII 編碼之后再進(jìn)行哈希,然后再將哈希之后的值進(jìn)行 BASE64-URL 編碼河泳,如下代碼所示沃呢。
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
在第一步獲取授權(quán)碼 code 的時候,我們使用 code_challenge 參數(shù)拆挥。需要注意的是薄霜,我們要同時將 code_challenge_method 參數(shù)也傳過去,目的是讓授權(quán)服務(wù)知道生成 code_challenge 值的方法是 plain 還是 S256纸兔。
https://authorization-server.com/auth?
response_type=code&
app_id=APP_ID&
redirect_uri=REDIRECT_URI&
code_challenge=CODE_CHALLENGE&
code_challenge_method=S256
在第二步獲取訪問令牌的時候惰瓜,我們使用 code_verifier 參數(shù),授權(quán)服務(wù)此時會將 code_verifier 的值進(jìn)行一次運(yùn)算汉矿。那怎么運(yùn)算呢崎坊?就是上面 code_challenge_method=S256 的這種方式。
沒錯洲拇,第一步請求授權(quán)碼的時候奈揍,已經(jīng)告訴授權(quán)服務(wù)生成 code_challenge 的方法了曲尸。所以,在第二步的過程中男翰,授權(quán)服務(wù)將運(yùn)算的值跟第一步接收到的值做比較另患,如果相同就頒發(fā)訪問令牌。
POST
https://api.authorization-server.com/token?
grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=REDIRECT_URI&
app_id=APP_ID&
code_verifier=CODE_VERIFIER
現(xiàn)在蛾绎,你就知道了我們是如何使用 code_verifier 和 code_challenge 這兩個參數(shù)的了吧昆箕。總結(jié)一下就是租冠,換取授權(quán)碼 code 的時候为严,我們使用 code_challenge 參數(shù)值;換取訪問令牌的時候肺稀,我們使用 code_verifier 參數(shù)值。
Keycloak介紹
Keycloak是為現(xiàn)代應(yīng)用和服務(wù)提供了開源IAM(Identity and Access Management)解決方案
https://www.keycloak.org/