全面了解OAuth?2.0四種授權(quán)方式金三銀四無(wú)懼面試
首先
我們需要清楚 OAuth 是什么?
OAuth 引入了一個(gè)授權(quán)層,用來(lái)分離兩種不同的角色:客戶端和資源所有者。......資源所有者同意以后,資源服務(wù)器可以向客戶端頒發(fā)令牌。客戶端通過(guò)令牌,去請(qǐng)求數(shù)據(jù)。
上面這段話的意思就是:OAuth 的核心就是向第三方應(yīng)用頒發(fā)令牌。
由于互聯(lián)網(wǎng)有多種場(chǎng)景,OAuth 2.0 規(guī)定了四種獲得令牌的流程,你可以選擇最適合自己的那一種,向第三方應(yīng)用頒發(fā)令牌。
下面就是這四種授權(quán)方式。
- 授權(quán)碼(authorization-code)
- 隱藏式(implicit)
- 密碼式(password)
- 客戶端憑證(client credentials)
注意,不管哪一種授權(quán)方式,第三方應(yīng)用申請(qǐng)令牌之前,都必須先到系統(tǒng)備案,說(shuō)明自己的身份,然后會(huì)拿到兩個(gè)身份識(shí)別碼:客戶端 ID(client ID)和客戶端密鑰(client secret)。
這是為了防止令牌被濫用,沒有備案過(guò)的第三方應(yīng)用,是不會(huì)拿到令牌的。
第一種授權(quán)方式:授權(quán)碼
授權(quán)碼(authorization code)方式,指的是第三方應(yīng)用先申請(qǐng)一個(gè)授權(quán)碼,然后再用該碼獲取令牌。
這種方式是最常用的流程,安全性也最高,它適用于那些有后端的 Web 應(yīng)用。授權(quán)碼通過(guò)前端傳送,令牌則是儲(chǔ)存在后端,而且所有與資源服務(wù)器的通信都在后端完成。這樣的前后端分離,可以避免令牌泄漏。
第一步,A 網(wǎng)站提供一個(gè)鏈接,用戶點(diǎn)擊后就會(huì)跳轉(zhuǎn)到 B 網(wǎng)站,授權(quán)用戶數(shù)據(jù)給 A 網(wǎng)站使用。下面就是 A 網(wǎng)站跳轉(zhuǎn) B 網(wǎng)站的一個(gè)示意鏈接。
https://b.com/oauth/authorize? response_type=code& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read
上面 URL 中,response_type參數(shù)表示要求返回授權(quán)碼(code),client_id參數(shù)讓 B 知道是誰(shuí)在請(qǐng)求,redirect_uri參數(shù)是 B 接受或拒絕請(qǐng)求后的跳轉(zhuǎn)網(wǎng)址,scope參數(shù)表示要求的授權(quán)范圍(這里是只讀)。
第二步,用戶跳轉(zhuǎn)后,B 網(wǎng)站會(huì)要求用戶登錄,然后詢問是否同意給予 A 網(wǎng)站授權(quán)。用戶表示同意,這時(shí) B 網(wǎng)站就會(huì)跳回redirect_uri參數(shù)指定的網(wǎng)址。跳轉(zhuǎn)時(shí),會(huì)傳回一個(gè)授權(quán)碼,就像下面這樣。
https://a.com/callback?code=AUTHORIZATION_CODE
上面 URL 中,code參數(shù)就是授權(quán)碼。
第三步,A 網(wǎng)站拿到授權(quán)碼以后,就可以在后端,向 B 網(wǎng)站請(qǐng)求令牌。
https://b.com/oauth/token? client_id=CLIENT_ID& client_secret=CLIENT_SECRET& grant_type=authorization_code& code=AUTHORIZATION_CODE& redirect_uri=CALLBACK_URL
上面 URL 中,client_id參數(shù)和client_secret參數(shù)用來(lái)讓 B 確認(rèn) A 的身份(client_secret參數(shù)是保密的,因此只能在后端發(fā)請(qǐng)求),grant_type參數(shù)的值是AUTHORIZATION_CODE,表示采用的授權(quán)方式是授權(quán)碼,code參數(shù)是上一步拿到的授權(quán)碼,redirect_uri參數(shù)是令牌頒發(fā)后的回調(diào)網(wǎng)址。
第四步,B 網(wǎng)站收到請(qǐng)求以后,就會(huì)頒發(fā)令牌。具體做法是向redirect_uri指定的網(wǎng)址,發(fā)送一段 JSON 數(shù)據(jù)。
{ "access_token":"ACCESS_TOKEN", "token_type":"bearer", "expires_in":2592000, "refresh_token":"REFRESH_TOKEN", "scope":"read", "uid":100101, "info":{...} }
上面 JSON 數(shù)據(jù)中,access_token字段就是令牌,A 網(wǎng)站在后端拿到了。
第二種方式:隱藏式
有些 Web 應(yīng)用是純前端應(yīng)用,沒有后端。這時(shí)就不能用上面的方式了,必須將令牌儲(chǔ)存在前端。RFC 6749 就規(guī)定了第二種方式,允許直接向前端頒發(fā)令牌。這種方式?jīng)]有授權(quán)碼這個(gè)中間步驟,所以稱為(授權(quán)碼)"隱藏式"(implicit)。
第一步,A 網(wǎng)站提供一個(gè)鏈接,要求用戶跳轉(zhuǎn)到 B 網(wǎng)站,授權(quán)用戶數(shù)據(jù)給 A 網(wǎng)站使用。
https://b.com/oauth/authorize? response_type=token& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read
上面 URL 中,response_type參數(shù)為token,表示要求直接返回令牌。
第二步,用戶跳轉(zhuǎn)到 B 網(wǎng)站,登錄后同意給予 A 網(wǎng)站授權(quán)。這時(shí),B 網(wǎng)站就會(huì)跳回redirect_uri參數(shù)指定的跳轉(zhuǎn)網(wǎng)址,并且把令牌作為 URL 參數(shù),傳給 A 網(wǎng)站。
https://a.com/callback#token=ACCESS_TOKEN
上面 URL 中,token參數(shù)就是令牌,A 網(wǎng)站因此直接在前端拿到令牌。
注意,令牌的位置是 URL 錨點(diǎn)(fragment),而不是查詢字符串(querystring),這是因?yàn)?OAuth 2.0 允許跳轉(zhuǎn)網(wǎng)址是 HTTP 協(xié)議,因此存在"中間人攻擊"的風(fēng)險(xiǎn),而瀏覽器跳轉(zhuǎn)時(shí),錨點(diǎn)不會(huì)發(fā)到服務(wù)器,就減少了泄漏令牌的風(fēng)險(xiǎn)。
這種方式把令牌直接傳給前端,是很不安全的。因此,只能用于一些安全要求不高的場(chǎng)景,并且令牌的有效期必須非常短,通常就是會(huì)話期間(session)有效,瀏覽器關(guān)掉,令牌就失效了。
第三種方式:密碼式
如果你高度信任某個(gè)應(yīng)用,RFC 6749 也允許用戶把用戶名和密碼,直接告訴該應(yīng)用。該應(yīng)用就使用你的密碼,申請(qǐng)令牌,這種方式稱為"密碼式"(password)。
第一步,A 網(wǎng)站要求用戶提供 B 網(wǎng)站的用戶名和密碼。拿到以后,A 就直接向 B 請(qǐng)求令牌。
https://oauth.b.com/token? grant_type=password& username=USERNAME& password=PASSWORD& client_id=CLIENT_ID
上面 URL 中,grant_type參數(shù)是授權(quán)方式,這里的password表示"密碼式",username和password是 B 的用戶名和密碼。
第二步,B 網(wǎng)站驗(yàn)證身份通過(guò)后,直接給出令牌。注意,這時(shí)不需要跳轉(zhuǎn),而是把令牌放在 JSON 數(shù)據(jù)里面,作為 HTTP 回應(yīng),A 因此拿到令牌。
這種方式需要用戶給出自己的用戶名/密碼,顯然風(fēng)險(xiǎn)很大,因此只適用于其他授權(quán)方式都無(wú)法采用的情況,而且必須是用戶高度信任的應(yīng)用。
第四種方式:憑證式
最后一種方式是憑證式(client credentials),適用于沒有前端的命令行應(yīng)用,即在命令行下請(qǐng)求令牌。
第一步,A 應(yīng)用在命令行向 B 發(fā)出請(qǐng)求。
https://oauth.b.com/token? grant_type=client_credentials& client_id=CLIENT_ID& client_secret=CLIENT_SECRET
上面 URL 中,grant_type參數(shù)等于client_credentials表示采用憑證式,client_id和client_secret用來(lái)讓 B 確認(rèn) A 的身份。
第二步,B 網(wǎng)站驗(yàn)證通過(guò)以后,直接返回令牌。
這種方式給出的令牌,是針對(duì)第三方應(yīng)用的,而不是針對(duì)用戶的,即有可能多個(gè)用戶共享同一個(gè)令牌。
令牌的使用
A 網(wǎng)站拿到令牌以后,就可以向 B 網(wǎng)站的 API 請(qǐng)求數(shù)據(jù)了。
此時(shí),每個(gè)發(fā)到 API 的請(qǐng)求,都必須帶有令牌。具體做法是在請(qǐng)求的頭信息,加上一個(gè)Authorization字段,令牌就放在這個(gè)字段里面。
curl -H "Authorization: Bearer ACCESS_TOKEN" \ "https://api.b.com"
上面命令中,ACCESS_TOKEN就是拿到的令牌。
更新令牌
令牌的有效期到了,如果讓用戶重新走一遍上面的流程,再申請(qǐng)一個(gè)新的令牌,很可能體驗(yàn)不好,而且也沒有必要。OAuth 2.0 允許用戶自動(dòng)更新令牌。
具體方法是,B 網(wǎng)站頒發(fā)令牌的時(shí)候,一次性頒發(fā)兩個(gè)令牌,一個(gè)用于獲取數(shù)據(jù),另一個(gè)用于獲取新的令牌(refresh token 字段)。令牌到期前,用戶使用 refresh token 發(fā)一個(gè)請(qǐng)求,去更新令牌。
https://b.com/oauth/token? grant_type=refresh_token& client_id=CLIENT_ID& client_secret=CLIENT_SECRET& refresh_token=REFRESH_TOKEN
上面 URL 中,grant_type參數(shù)為refresh_token表示要求更新令牌,client_id參數(shù)和client_secret參數(shù)用于確認(rèn)身份,refresh_token參數(shù)就是用于更新令牌的令牌。
B 網(wǎng)站驗(yàn)證通過(guò)以后,就會(huì)頒發(fā)新的令牌。
參考:OAuth 2.0
以上就是全面了解OAuth 2.0四種授權(quán)方式金三銀四無(wú)懼面試的詳細(xì)內(nèi)容,更多關(guān)于OAuth 2.0面試四種授權(quán)方式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java實(shí)現(xiàn)添加條碼或二維碼到Word文檔
這篇文章主要介紹了如何在Word文檔中添加條碼、二維碼??稍谖臋n正文段落中添加,也可在頁(yè)眉頁(yè)腳中添加,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下吧2022-05-05JavaWeb中HttpSession中表單的重復(fù)提交示例
這篇文章主要介紹了JavaWeb中HttpSession中表單的重復(fù)提交,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03Spring?框架的?MethodInterceptor?簡(jiǎn)介及示例代碼
MethodInterceptor接口定義了一個(gè)方法Object?intercept(Object?obj,?Method?method,?Object[]?args,?MethodProxy?proxy)?,該方法在代理對(duì)象的方法被調(diào)用時(shí)被觸發(fā),這篇文章主要介紹了Spring?框架的?MethodInterceptor?簡(jiǎn)介及示例代碼,需要的朋友可以參考下2023-09-09Spring中的事件監(jiān)聽器使用學(xué)習(xí)記錄
Spring框架中的事件監(jiān)聽機(jī)制是一種設(shè)計(jì)模式,它允許你定義和觸發(fā)事件,同時(shí)允許其他組件監(jiān)聽這些事件并在事件發(fā)生時(shí)作出響應(yīng),這篇文章主要介紹了Spring中的事件監(jiān)聽器使用學(xué)習(xí),需要的朋友可以參考下2024-07-07簡(jiǎn)單分析Java線程編程中ThreadLocal類的使用
這篇文章主要介紹了Java線程編程中ThreadLocal類的使用,包括使用其對(duì)共享變量的操作的分析,需要的朋友可以參考下2015-12-12java中使用session監(jiān)聽實(shí)現(xiàn)同帳號(hào)登錄限制、登錄人數(shù)限制
本文主要介紹了java中使用session監(jiān)聽實(shí)現(xiàn)同帳號(hào)登錄限制、登錄人數(shù)限制,通過(guò)session來(lái)監(jiān)聽在線人數(shù)和登陸限制,有需要的童鞋可以了解一下。2016-10-10利用Java實(shí)現(xiàn)天氣預(yù)報(bào)播報(bào)功能
這篇文章主要為大家介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)天氣預(yù)報(bào)播報(bào)功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下2022-06-06