當前位置:
首頁 > 最新 > 理解OAuth2.0授權

理解OAuth2.0授權

-這是小明同學2018年第5篇文章-

一、什麼是OAuth

二、什麼場景下會用到OAuth授權

三、OAuth 2.0中的4個成員

四、OAuth 2.0授權流程

五、OAuth 2.0授權模式

1、authorizationcode(授權碼模式)

2、implicit(簡化模式)

3、resource ownerpassword credentials(密碼模式)

4、clientcredentials(客戶端模式)

六、小結

一、什麼是OAuth

所謂的OAuth(Open Authorization)本質上就是一張開放的協議,OAuth協議為用戶資源的授權提供了一個安全的、開放而又簡易的標準。與以往的授權方式不同該授權不會使第三方觸及到用戶的賬戶信息,即第三方無需使用用戶名密碼就可以申請該用戶資源的授權,因此OAuth是安全的。這是來自百度百科對OAuth的解釋。

而OAuth2.0呢,故名思義就是OAuth的下一個版本,同時它也是授權領域的行業標準協議,OAuth2.0不支持向後兼容,即不支持OAuth1.0,徹底廢止了OAuth1.0協議,OAuth2.0致力於使客戶端開發者通過更簡單的流程為Web應用、桌面應用以及手機客戶端等設備進行授權。2012年10月,OAuth2.0協議正式發布為RFC6749。目前各大開放平台,如騰訊、新浪、百度等等也都是以OAuth2.0協議作為支撐。

二、什麼場景下會用到OAuth授權

目前我們大多數的應用場景,也是我們最熟悉的使用環境就是使用第三方登錄,如:微博,QQ,微信,豆瓣等社交平台登錄,互聯網發展到今天,我們也都習慣了這種登錄方式,最大的好處就是便捷,簡化了我們一系列的註冊流程,還有一大堆帳號密碼記不住的困擾,當你碰到一個不支持第三方登錄的網站或者應用的時候,第一感覺就是厭惡,一頓噴。人永遠離不開社交,所以通過社交平台去登錄其他的平台,無疑是最受大家歡迎的方式了。傳統的認證方式

就拿CSDN為例,CSDN是支持第三方平台登錄的,截圖如下:

若用戶想使用QQ登錄,那麼在傳統的認證模式中,客戶端(CSDN)請求訪問伺服器上受限的資源(QQ),需要通過資源所有者(用戶的QQ賬戶)的憑證在伺服器上進行認證。為了支持第三方應用程序(對於QQ來說,CSDN是第三方應用程序,是CSDN去請求訪問QQ的資源)訪問受限資源,資源所有者需要向第三方應用共享其憑證(如用戶QQ的帳號和密碼)。那這樣就會造成以下幾個問題:

·第三方應用(CSDN)為了以後繼續使用,那麼會存儲資源所有者的憑證,如密碼;

·服務端需要支持密碼認證,儘管密碼認證不安全;

·第三方應用若想訪問資源所有者的其他資源,資源所有者無法對其進行限制;

·資源所有者無法收回第三方的訪問許可權,除非用戶主動修改密碼;

·如果此時第三方的數據泄漏,那也會導致資源所有者其他數據的泄漏,造成重大損失。

若此時,CSDN知道了用戶的QQ密碼,那CSDN可以任意去訪問該用戶的所有信息,而QQ無法去限制它的訪問,這不管是對QQ還是用戶本身都會是一件可怕的事,作為使用者,你永遠都無法知道應用都幹了些什麼。由此OAuth2.0的出現,就是為了解決這樣的問題。

三、OAuth 2.0中的4個成員

在OAuth2.0中有4個成員,Resource Owner、ResourceServer、Client、AuthorizationServer,如圖所示:

在上面4個成員中,授權伺服器可能與資源伺服器在同一台伺服器。

四、OAuth 2.0授權流程

流程如下,圖片來自RFC6749:

流程解析:

1.用戶打開客戶端,客戶端要求向資源所有者(即用戶)給予授權;

2.用戶同意授權;

3.客戶端得知用戶同意授權後,向授權伺服器獲取授權;

4.授權伺服器給予客戶端授權,並將授權碼(Access Token);

5.客戶端攜帶授權碼去請求資源伺服器;

6.資源伺服器將受限的資源開放給客戶端。

五、OAuth 2.0授權模式

授權許可是表示客戶用來獲取訪問令牌的資源所有者授權的憑證。此規範協議規定了4種授權類型:

·authorization code(授權碼模式)

·implicit(簡化模式)

·resource owner password credentials(密碼模式)

·client credentials(客戶端模式)

下面詳細說明各種授權模式的具體流程:

1、authorization code(授權碼模式)

授權代碼授權類型用於獲取訪問令牌和刷新令牌,並針對機密客戶端進行優化。它是一個基於重定向的流程,因此客戶端必須能夠與資源所有者的用戶代理(通常是Web瀏覽器)並且能夠從授權伺服器接收傳入請求(通過重定向)。授權碼模式是功能最完整、流程最嚴密的授權模式,它的特點就是通過客戶端的後台伺服器,與"服務提供商"的授權伺服器進行互動。授權流程如下:

流程解析:

1.客戶端通過用戶代理,重定向請求授權伺服器,所需參數:客戶端標識及重定向URL;

2.用戶選擇是否給予客戶端授權;

3.授權伺服器給予客戶端一個認證授權碼,並跳轉到指定的URI;

4.客戶端使用該授權碼,重定向到授權伺服器,獲取令牌;

5.授權伺服器校驗該授權碼以及重定向的URI後,向客戶端發送令牌或者更新令牌。

以上均個人解釋,簡化了RFC6749官方文檔說明,大致意思是一樣的。注意的一點是,在用戶同意授權後,授權伺服器並未直接將令牌發送給客戶端,而是先向客戶端發送了一個授權碼,authorization code,然後再攜帶該授權碼,再一次請求授權伺服器,校驗無誤後,再發送令牌(access token),這一步是在後台自動完成的,這樣也使OAuth授權更加安全。

在該授權流程中,我們所需的幾個參數,官方文檔中要求指定的參數如下:

·response_type必選項 表示的是要求指定的授權類型,此處必須設置為:code

·client_id必選項 客戶端的唯一標識

·redirect_uri可選項 重定向的URI

·scope可選項 授權的管道

·state建議項 表示客戶端狀態,授權伺服器會將該狀態原值返回

看完該流程以及所需的參數後,我們結合實際情況,還是上面提到的例子,以CSDN使用QQ登錄為例,看一下該過程:

(A步驟)點擊QQ登錄,跳轉到QQ帳號安全登錄界面,即騰訊的互聯平台,我們可以直接拿到此時CSDN要請求的地址:

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&

response_type=code&

redirect_uri=https://passport.csdn.net/account/login?oauth_provider=QQProvider&

state=test

這樣我們可以很清楚的看到在上面的URL中,發起了一個get請求,他的授權類型為code 授權碼模式,以及client_id,redirect_uri,state等信息,而此時頁面也跳轉到了用戶代理的頁面,讓用戶去決定是否要同意授權:

(C步驟)當用戶輸入用戶名密碼後點擊授權並登錄,伺服器會先驗證你輸入的是否正確,如果正確,頁面就會跳轉到redirect_uri的地址中,而在這個過程中發生的變化是這樣的,我們繼續查看這時的URL地址:

https://passport.csdn.net/account/login?oauth_provider=QQProvider&

code=D185F3ED93E4F1B3C5F557E6112C7A9B&

state=test

(D步驟)我們可以看到授權並登錄後它重定向到了我們指定的地址,而且還給予了一個code授權碼,另外state狀態還是在請求登錄時的狀態,在下一個步驟中,是客戶端向授權伺服器申請令牌,包含以下參數:

·grant_type表示授權模式,此處固定為authorization_code,必選

·code表示上一步獲取到的授權碼,必選

·redirect_uri表示重定向URI,必選

·client_id表示客戶端ID,必選

在使用騰訊開放平台時,它會要求有一個client_secrect,是對應你客戶端ID的一個私鑰,它也是在客戶端註冊時產生的,所以在使用QQ登錄獲取令牌時,也必須指定該選項:client_secret,具體的可以看騰訊的開發文檔。那麼實際上申請令牌的這個過程我們是看不到的,返回authorization code 後,我們會看到我們的客戶端此時已經登錄成功了。例如:

POST/token HTTP/1.1

Host:graph.qq.com/oauth2.0/token

Authorization:Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type:application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA

&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&client_secret=fdhsjfdsj32jjfhjdk

(E步驟)若以上返回成功,那麼在E步驟中會返回如下信息:

HTTP/1.1200 OK

Content-Type:application/json;charset=UTF-8

Cache-Control:no-store

Pragma:no-cache

{

"access_token":"2YotnFZFEjr1zCsicMWpAA",

"token_type":"example",

"expires_in":3600,

"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",

"example_parameter":"example_value"

}

裡面包含了我們所需要的令牌access token以及有效期等信息。實際上在我們實際應用過程中,我們不止是到這裡就結束了,我們會使用access token令牌再去請求資源伺服器,獲取可以被調用的資源,以及一些其他的操作。

2、implicit(簡化模式)

簡化模式用於獲取訪問令牌(但它不支持令牌的刷新),並對運行特定重定向URI的公共客戶端進行優化,而這一些列操作通常會使用腳本語言在瀏覽器中完成,令牌對訪問者是可見的,且客戶端也不需要驗證。具體流程如下:

步驟解析:

1.客戶端攜帶客戶端標識以及重定向URI到授權伺服器;

2.用戶確認是否要授權給客戶端;

3.授權伺服器得到許可後,跳轉到指定的重定向地址,並將令牌也包含在了裡面;

4.客戶端不攜帶上次獲取到的包含令牌的片段,去請求資源伺服器;

5.資源伺服器會向瀏覽器返回一個腳本;

6.瀏覽器會根據上一步返回的腳本,去提取在C步驟中獲取到的令牌;

7.瀏覽器將令牌推送給客戶端。

(A步驟)中需要用到的參數,注意在這裡要使用"application/x-www-form-urlencoded"格式:

·response_type必選項,此值必須為"token"

·client_id必選項

·redirect_uri可選項

·scope可選項

·state建議選項

例如:

GET/authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz

&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1

(C步驟)中返回的參數包含:

·access_token必選項

·token_type必選項

·expires_in建議選項

·scope可選項

·state必選項

例如:

HTTP/1.1 302 Found

Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA

&state=xyz&token_type=example&expires_in=3600

3、resourceowner password credentials(密碼模式)

密碼模式適合建立在客戶端與資源所有者具有信任關係的情況下,例如它是一個設備的操作系統或者具有很高許可權的應用。這種模式用戶要向客戶端提供自己的用戶名密碼,從而達到向服務提供商索取授權。授權伺服器在啟動此類型時,要特別小心,只有在其他的授權方式不被允許的情況下才可以使用這種授權模式。流程如下:

1.客戶端要求使用資源所有者的密碼;

2.資源所有者給予用戶名密碼後,客戶端向授權伺服器發起申請令牌的請求;

3.授權伺服器將令牌發放給客戶端。

步驟解析:

(B步驟)所需參數:

·grant_type必選項 此值必須為"password"

·username必選項 用戶名

·password必選項 密碼

·scope可選項

例如:

POST/token HTTP/1.1

Authorization:Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type:application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=A3ddj3w

(C步驟)發放令牌:

HTTP/1.1 200 OK

Content-Type: application/json;charset=UTF-8

Cache-Control: no-store

Pragma: no-cache

{

"access_token":"2YotnFZFEjr1zCsicMWpAA",

"token_type":"example",

"expires_in":3600,

"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",

"example_parameter":"example_value"

}

4、clientcredentials(客戶端模式)

客戶端模式是4種模式中最簡單的一種模式。客戶端可以使用客戶端憑據請求訪問令牌(或者其他支持的認證方式),在這種模式中,客戶端佔據主導地位,它不需要用戶的同意,可以直接向授權伺服器索取令牌,嚴格來說,該模式並不存在授權的問題,流程如下:

1.客戶端向授權伺服器發起請求索要令牌;

2.授權伺服器將令牌發放給客戶端。

步驟解析:

(A步驟)中所需的參數::

·grant_type必選項 此值必須為client_crendentials

·scope可選項

例如:

POST /token HTTP/1.1

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

(B步驟)授權伺服器返回結果:

HTTP/1.1 200 OK

Content-Type: application/json;charset=UTF-8

Cache-Control: no-store

Pragma: no-cache

{

"access_token":"2YotnFZFEjr1zCsicMWpAA",

"token_type":"example",

"expires_in":3600,

"example_parameter":"example_value"

}

六、小結


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 全球大搜羅 的精彩文章:

還是要記住從前
假如你還有兩年可活會怎樣?

TAG:全球大搜羅 |