一口氣說(shuō)出 OAuth2.0 的四種授權(quán)方式
掃描二維碼
隨時(shí)隨地手機(jī)看文章
上周我的自研開(kāi)源項(xiàng)目開(kāi)始破土動(dòng)工了,《開(kāi)源項(xiàng)目邁出第一步,10 選 1?頁(yè)面模板成了第一個(gè)絆腳石 》 ,密謀很久才付諸行動(dòng),做這個(gè)的初衷就是不想讓自己太安穩(wěn),技術(shù)這條路不進(jìn)步就等于后退,必須要逼著自己學(xué)習(xí)。
項(xiàng)目偏向于技術(shù)實(shí)踐,因此不會(huì)做太多的業(yè)務(wù)堆砌,業(yè)務(wù)代碼還是在公司學(xué)習(xí)比較好。現(xiàn)在正在做技術(shù)的選型與儲(chǔ)備,像比較主流的,項(xiàng)目前后端分離
、微服務(wù)
、Springboot
、Springcloud
等都會(huì)應(yīng)用到項(xiàng)目中,其實(shí)很多技術(shù)我也不會(huì),也是在反復(fù)的查閱資料求證,探索的過(guò)程技術(shù)提升真的要比工作中快很多,畢竟主動(dòng)與被動(dòng)學(xué)習(xí)是有本質(zhì)區(qū)別的。
這幾天打算先把項(xiàng)目的前后端分離架構(gòu)搭建完成,既然是前后端分離項(xiàng)目就免不了做鑒權(quán), 所以 oauth2.0
是一個(gè)我們不得不了解的知識(shí)點(diǎn)。
一、OAuth2.0 為何物
OAuth
簡(jiǎn)單理解就是一種授權(quán)機(jī)制,它是在客戶端和資源所有者之間的授權(quán)層,用來(lái)分離兩種不同的角色。在資源所有者同意并向客戶端頒發(fā)令牌后,客戶端攜帶令牌可以訪問(wèn)資源所有者的資源。
OAuth2.0
是OAuth
協(xié)議的一個(gè)版本,有2.0
版本那就有1.0
版本,有意思的是OAuth2.0
卻不向下兼容OAuth1.0
,相當(dāng)于廢棄了1.0
版本。
舉個(gè)小栗子解釋一下什么是 OAuth 授權(quán)?
在家肝文章餓了定了一個(gè)外賣,外賣小哥30秒火速到達(dá)了我家樓下,奈何有門(mén)禁進(jìn)不來(lái),可以輸入密碼進(jìn)入,但出于安全的考慮我并不想告訴他密碼。
此時(shí)外賣小哥看到門(mén)禁有一個(gè)高級(jí)按鈕“一鍵獲取授權(quán)
”,只要我這邊同意,他會(huì)獲取到一個(gè)有效期 2小時(shí)的令牌(token
)正常出入。

token
)和
密碼
的作用雖然相似都可以進(jìn)入系統(tǒng),但還有點(diǎn)不同。
token
擁有權(quán)限范圍,有時(shí)效性的,到期自動(dòng)失效,而且無(wú)效修改。
二、OAuth2.0 授權(quán)方式
OAuth2.0
的授權(quán)簡(jiǎn)單理解其實(shí)就是獲取令牌(token
)的過(guò)程,OAuth
協(xié)議定義了四種獲得令牌的授權(quán)方式(authorization grant
)如下:
-
授權(quán)碼( authorization-code
) -
隱藏式( implicit
) -
密碼式( password
): -
客戶端憑證( client credentials
)
但值得注意的是,不管我們使用哪一種授權(quán)方式,在三方應(yīng)用申請(qǐng)令牌之前,都必須在系統(tǒng)中去申請(qǐng)身份唯一標(biāo)識(shí):客戶端 ID(client ID
)和 客戶端密鑰(client secret
)。這樣做可以保證 token
不被惡意使用。
下面我們會(huì)分析每種授權(quán)方式的原理,在進(jìn)入正題前,先了解 OAuth2.0
授權(quán)過(guò)程中幾個(gè)重要的參數(shù):
-
response_type
:code 表示要求返回授權(quán)碼,token 表示直接返回令牌 -
client_id
:客戶端身份標(biāo)識(shí) -
client_secret
:客戶端密鑰 -
redirect_uri
:重定向地址 -
scope
:表示授權(quán)的范圍,read
只讀權(quán)限,all
讀寫(xiě)權(quán)限 -
grant_type
:表示授權(quán)的方式,AUTHORIZATION_CODE
(授權(quán)碼)、password
(密碼)、client_credentials
(憑證式)、refresh_token
更新令牌 -
state
:應(yīng)用程序傳遞的一個(gè)隨機(jī)數(shù),用來(lái)防止CSRF
攻擊。
1、授權(quán)碼
OAuth2.0
四種授權(quán)中授權(quán)碼方式是最為復(fù)雜,但也是安全系數(shù)最高的,比較常用的一種方式。這種方式適用于兼具前后端的Web
項(xiàng)目,因?yàn)橛行╉?xiàng)目只有后端或只有前端,并不適用授權(quán)碼模式。
下圖我們以用WX
登錄掘金為例,詳細(xì)看一下授權(quán)碼方式的整體流程。

用戶選擇WX
登錄掘金,掘金會(huì)向WX
發(fā)起授權(quán)請(qǐng)求,接下來(lái) WX
詢問(wèn)用戶是否同意授權(quán)(常見(jiàn)的彈窗授權(quán))。response_type
為 code
要求返回授權(quán)碼,scope
參數(shù)表示本次授權(quán)范圍為只讀權(quán)限,redirect_uri
重定向地址。
https://wx.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=http://juejin.im/callback&
scope=read
用戶同意授權(quán)后,WX
根據(jù) redirect_uri
重定向并帶上授權(quán)碼。
http://juejin.im/callback?code=AUTHORIZATION_CODE
當(dāng)掘金拿到授權(quán)碼(code)時(shí),帶授權(quán)碼和密匙等參數(shù)向WX
申請(qǐng)令牌。grant_type
表示本次授權(quán)為授權(quán)碼方式 authorization_code
,獲取令牌要帶上客戶端密匙 client_secret
,和上一步得到的授權(quán)碼 code
。
https://wx.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=http://juejin.im/callback
最后 WX
收到請(qǐng)求后向 redirect_uri
地址發(fā)送 JSON
數(shù)據(jù),其中的access_token
就是令牌。
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
......
}
2、隱藏式
上邊提到有一些Web
應(yīng)用是沒(méi)有后端的, 屬于純前端應(yīng)用,無(wú)法用上邊的授權(quán)碼模式。令牌的申請(qǐng)與存儲(chǔ)都需要在前端完成,跳過(guò)了授權(quán)碼這一步。
前端應(yīng)用直接獲取 token
,response_type
設(shè)置為 token
,要求直接返回令牌,跳過(guò)授權(quán)碼,WX
授權(quán)通過(guò)后重定向到指定 redirect_uri
。
https://wx.com/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=http://juejin.im/callback&
scope=read
3、密碼式
密碼模式比較好理解,用戶在掘金直接輸入自己的WX
用戶名和密碼,掘金拿著信息直接去WX
申請(qǐng)令牌,請(qǐng)求響應(yīng)的 JSON
結(jié)果中返回 token
。grant_type
為 password
表示密碼式授權(quán)。
https://wx.com/token?
grant_type=password&
username=USERNAME&
password=PASSWORD&
client_id=CLIENT_ID
這種授權(quán)方式缺點(diǎn)是顯而易見(jiàn)的,非常的危險(xiǎn),如果采取此方式授權(quán),該應(yīng)用一定是可以高度信任的。
4、憑證式
憑證式和密碼式很相似,主要適用于那些沒(méi)有前端的命令行應(yīng)用,可以用最簡(jiǎn)單的方式獲取令牌,在請(qǐng)求響應(yīng)的 JSON
結(jié)果中返回 token
。
grant_type
為 client_credentials
表示憑證式授權(quán),client_id
和 client_secret
用來(lái)識(shí)別身份。
https://wx.com/token?
grant_type=client_credentials&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
三、令牌的使用與更新
1、令牌怎么用?
拿到令牌可以調(diào)用 WX
API 請(qǐng)求數(shù)據(jù)了,那令牌該怎么用呢?
每個(gè)到達(dá)WX
的請(qǐng)求都必須帶上 token
,將 token
放在 http
請(qǐng)求頭部的一個(gè)Authorization
字段里。
如果使用postman
模擬請(qǐng)求,要在Authorization
-> Bearer Token
放入 token
,注意:低版本postman
沒(méi)有這個(gè)選項(xiàng)。

2、令牌過(guò)期怎么辦?
token
是有時(shí)效性的,一旦過(guò)期就需要重新獲取,但是重走一遍授權(quán)流程,不僅麻煩而且用戶體驗(yàn)也不好,那如何讓更新令牌變得優(yōu)雅一點(diǎn)呢?
一般在頒發(fā)令牌時(shí)會(huì)一次發(fā)兩個(gè)令牌,一個(gè)令牌用來(lái)請(qǐng)求API
,另一個(gè)負(fù)責(zé)更新令牌 refresh_token
。grant_type
為 refresh_token
請(qǐng)求為更新令牌,參數(shù) refresh_token
是用于更新令牌的令牌。
https://wx.com/oauth/token?
grant_type=refresh_token&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
refresh_token=REFRESH_TOKEN
總結(jié)
OAuth2.0
授權(quán)其實(shí)并不是很難,只不過(guò)授權(quán)流程稍顯麻煩,邏輯有些繞,OAuth2.0
它是面試經(jīng)常會(huì)被問(wèn)到的知識(shí)點(diǎn),還是應(yīng)該多了解一下。下一篇實(shí)戰(zhàn) OAuth2.0
四種授權(quán),敬請(qǐng)期待,歡迎關(guān)注哦~
特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒(méi)關(guān)注的小伙伴,可以長(zhǎng)按關(guān)注一下:
長(zhǎng)按訂閱更多精彩▼
如有收獲,點(diǎn)個(gè)在看,誠(chéng)摯感謝
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!