Oauth2.0本身:
Oauth2.0是一種授權(quán)協(xié)議,當(dāng)然也歸屬為安全協(xié)議的范疇,在實際執(zhí)行的時候就是保護(hù)互聯(lián)網(wǎng)中不斷增長的大量WEB API的安全訪問。OAuth2.0共包含四種角色,分別是資源所有者、第三方應(yīng)用(也稱為客戶端client)、授權(quán)服務(wù)器和資源服務(wù)器。如下圖所示,某公司A開發(fā)了一個微信小程序(第三方應(yīng)用)可以幫助我(資源所有者)美化微信服務(wù)器(資源服務(wù)器)上面的頭像,我在用這個微信小程序開發(fā)的美化頭像功能的時候,首先要給微信小程序授權(quán)(授權(quán)服務(wù)器),這個微信小程序才能訪問我的頭像,實際上訪問的時候微信小程序就是通過WEB API來調(diào)用的。授權(quán)的過程中我是不可能把我的賬號密碼給它的,這樣的前提下就會有另外方式的授權(quán),也就是上面介紹的現(xiàn)在國際通用的標(biāo)準(zhǔn)OAuth2.0。
OAuth2.0協(xié)議流程描述了四種角色之間的交互過程,如下圖所示。
上面的序列圖一共分為以下6個步驟:
(1)第三方應(yīng)用請求資源所有者授權(quán)。
(2)資源所有者同意給第三方應(yīng)用授權(quán)。
(3)第三方應(yīng)用使用步驟2中獲得的授權(quán),向授權(quán)服務(wù)器申請令牌。
(4)授權(quán)服務(wù)器對第三方應(yīng)用進(jìn)行認(rèn)證并確認(rèn)無誤后,同意發(fā)放令牌。
(5)第三方應(yīng)用使用步驟4中發(fā)放的令牌向資源服務(wù)器申請獲取資源。
(6)資源服務(wù)器確認(rèn)令牌無誤后,向第三方應(yīng)用開放資源訪問。
關(guān)于更詳細(xì)的Oauth2.0流程介紹,也可以參考《架構(gòu)修煉之道》第2章 "開放之道" 內(nèi)容。
第三方開發(fā)者ISV的實踐:
如果按照開發(fā)語言類型來區(qū)分可以有JAVA、.net、PHP等不同的ISV應(yīng)用類型,但語言分類對于授權(quán)的場景意義不大,因為雖然是不同的語言但大家都是遵守Oauth2.0協(xié)議。在授權(quán)上區(qū)分ISV接入流程我們則需要按照ISV應(yīng)用有無Web Server來區(qū)分。有Web Server的歸為一類,走Server-side flow;沒有Web Serve的歸為另外一類,走Client-side flow流程。
本文先介紹Server-side flow流程,共包含3個步驟。
步驟一:****拼接授權(quán)URL
以京東宙斯開放平臺為例
https://open-oauth.jd.com/oauth2/to_login?app_key=XXXXX&response_type=code&redirect_uri=XXXXX
有三個必填參數(shù),分別是app_key,response_type,redirect_uri,下面是該三個參數(shù)的具體含義。
| 名稱 | 是否必填 | 參數(shù)值 |
|---|---|---|
| app_key | 是 | ISV在宙斯開放平臺創(chuàng)建應(yīng)用的時候由系統(tǒng)分配 |
| response_type | 是 | 固定值code,默認(rèn)采用code換取token的方式 |
| redirect_uri | 是 | ISV的應(yīng)用訪問地址,創(chuàng)建應(yīng)用的時候由ISV配置 |
PS:左右滑動查看完整列表
注:如果是通過開放平臺直接使用,ISV可以不用拼接該授權(quán)URL,會由開放平臺一方的系統(tǒng)自動讀取ISV的應(yīng)用地址然后拼接好返回給客戶端,后文在平臺一方的實踐介紹中有敘述。
步驟二:****引導(dǎo)用戶登錄授權(quán)
引導(dǎo)用戶登錄,并為ISV應(yīng)用進(jìn)行授權(quán)。
步驟三:****獲取CODE
在用戶登錄并點擊授權(quán)之后宙斯會將授權(quán)碼CODE返回到回調(diào)地址上,比如https://redirect_uri?code=CODE&...
ISV獲取到CODE之后就可以執(zhí)行步驟四。
步驟四:****用CODE換取ACCESSTOKEN
https://open-oauth.jd.com/oauth2/access_token?app_key=XXXXX&app_secret=XXXXX&grant_type=authorization_code&code=XXXXX,這里的code是通過步驟三獲取到的。
| 名稱 | 是否必填 | 參數(shù)值 |
|---|---|---|
| app_key | 是 | ISV在宙斯開放平臺創(chuàng)建應(yīng)用的時候由系統(tǒng)分配 |
| app_secret | 是 | 宙斯開放平臺分配給當(dāng)前app_key對應(yīng)的應(yīng)用的秘鑰 |
| grant_type | 是 | 固定為authorization_code |
| code | 是 | 步驟三中獲取到的值 |
返回值示例:
{
access_token: "a3207b6b5ad04249ad1dbf6a98248bea",//所需要的access_token
expires_in: 3600000,//單位ms,該access_token的過期時間
refresh_token: "4ecbbab0e9e443159c518da1d10741ad"http://再不需要用戶重新授權(quán)的情況下,用于獲取新的access_token
}
access_token是有有效期的,這一點是從安全角度來考慮的,因為如果access_token沒有時效性,一旦泄露則會被攻擊者長期使用。好比我們的個人密碼需要定期修改一樣。比如筆者跟公司簽訂了五年期的合同,在這個五年時間內(nèi)公司要求我們的內(nèi)部ERP系統(tǒng)的密碼需要三個月更新一次,這樣避免了密碼一旦泄露造成了長期的安全風(fēng)險。在訂購類型的第三方IT工具類應(yīng)用中access_token是用戶授權(quán)之后ISV的應(yīng)用才能獲取到的,比如用戶購買了該ISV的一款SASS軟件為期6個月。如果這6個月時間內(nèi)出于安全考慮需要更新access_token的值,肯定不能讓用戶再授權(quán)一次,這樣體驗非常不友好。此時refresh_token就派上了用場,ISV可以利用refresh_token去請求開放平臺獲取新的access_token的值。
當(dāng)用戶授權(quán)ISV之后會獲取到一個accestoken,對于ISV來講accestoken相當(dāng)于登錄成功了ISV軟件之后的PIN。此時ISV需要將這個用戶的accestoken會話保存下來,可以加密存儲到cookie中,也可以放到ISV軟件服務(wù)端的session中。ISV軟件后續(xù)訪問平臺的接口要求必須都要有該accestoken,這樣會話狀態(tài)被保存下來之后則會使得ISV應(yīng)用調(diào)用平臺接口更加的便利,實際上相當(dāng)于用戶登錄了一個普通的WEB應(yīng)用之后,每次這個WEB應(yīng)用服務(wù)端程序都能獲取到該用戶的會話信息一樣。
平臺一方的實踐:
我作為一個用戶需要授權(quán)給我當(dāng)前將要使用的軟件服務(wù)商,這樣軟件服務(wù)商才可以被允許去訪問我的數(shù)據(jù)。理論上我是需要每次都進(jìn)行授權(quán)動作才能完成軟件的使用,那么我們平時會發(fā)現(xiàn)比如在微信中使用第三方小程序的時候我只在第一次訪問的時候進(jìn)行了授權(quán)動作,以后使用的時候并沒有要求我再次進(jìn)行授權(quán),這是如何實現(xiàn)的呢。再比如下圖所示,在用戶點擊立即使用的時候也會遇到同樣的場景:初次使用和再次使用。
這就需要作為平臺一方來實現(xiàn)控制邏輯,同時這個也建立在用戶在平臺使用的基礎(chǔ)之上。平臺一方在第一次用戶授權(quán)之后會按照Oauth2.0的規(guī)范生成一個accesstoken,隨后將該accesstoken與當(dāng)前用戶的pin進(jìn)行綁定存儲到數(shù)據(jù)庫中,如下圖所示。當(dāng)然該授權(quán)關(guān)系是有時效的(這個時效需要依據(jù)平臺的實際環(huán)境來確定)。當(dāng)用戶再次來通過平臺去訪問該軟件的時候,平臺會根據(jù)當(dāng)前登錄的用戶pin去判斷先前已經(jīng)保存的綁定關(guān)系,如果有綁定關(guān)系則允許用戶直接使用軟件,在返回的startUrl中是一個帶有code的ISV軟件的啟動地址,如果沒有綁定關(guān)系則會直接利用第三方開發(fā)者已經(jīng)接入的規(guī)范的Oauth2.0協(xié)議流程,返回的startUrl中是一個授權(quán)的頁面地址,由第三方開發(fā)者去引導(dǎo)用戶進(jìn)行授權(quán)。
總結(jié)
本文先后從概念到開發(fā)者實踐以及平臺一方的實踐去介紹了Oauth2.0。它是一個基于HTTP的協(xié)議,如果采用授權(quán)碼類型比如本文中所述的Server-side flow則要求必須有Web Server,我們也正是按照該流程去介紹如何實踐的。
想了解Oauth2.0的同學(xué)請持續(xù)關(guān)注,未完待續(xù)... 文章第一時間發(fā)布在公眾號