OAuth2基本概念和运作流程
OAuth2基本概念和運作流程
?
OAuth(開放授權)是一個關于授權的開放標準,允許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密的資源(如照片,視頻,聯系人列表),而無需將用戶名和密碼提供給第三方應用。目前的版本是2.0版,本文將對OAuth2.0的一些基本概念和運行流程做一個簡要介紹。主要參考RFC-6749。
應用場景
這里有兩個典型的例子:
- 比如你瀏覽某個網站的技術文章,發現其中某段介紹的不夠詳細,想留言給作者提問,點擊評論,結果發現需要有這個網站的賬號才能留言,此時有兩個選擇,一個是新注冊一個此網站的賬號,二是點擊通過github快速登錄。前者你覺得過于繁瑣,直接點擊了github登錄,此時,OAuth的認證流程就開始了。通過引導跳轉到github界面,會提示你是否授權該網站使用你的github用戶信息,點擊確認,跳轉回原網站,發現已經使用你的github賬號默認注冊了一個用戶,而且還不需要用戶名和密碼,便捷高效。
-
假如有一個云沖印的網站,可以將你存儲在Google的照片沖印出來,用戶為了使用該服務,必須讓云沖印讀取Google上的照片。為了拿到照片,云沖印必須得拿到一個用戶的授權,如何獲取這個用戶授權呢?傳統方法是用戶將用戶名和密碼告訴云沖印,那么云沖印就可以自由無限制的訪問了(相當于用戶自己訪問),這樣顯然是不行的,有幾個嚴重的缺點:
- 云沖印為了保存后續服務,會保存用戶的密碼,這樣很不安全。
- 云沖印擁有了獲取用戶存儲在Google的所有資料的權力,用戶沒法限制云沖印得到的授權范圍和授權有效期。
- 用戶只有修改密碼,才能收回賦予云沖印的權力,但是如果還授權給了其他的應用,那么密碼的修改將影響到所有被授權應用。
- 只要有一個第三方應用程序被破解,就會導致用戶密碼泄漏,以及所有被密碼保護的數據泄漏。(例子來自阮一峰-理解OAuth2.0)
可以看出,OAuth就是為解決如上例子而誕生的。
名詞解釋
以下幾個名詞至關重要:
- Resource Owner:資源所有者。即用戶。
- Client:客戶端(第三方應用)。如云沖印。
- HTTP service:HTTP服務提供商,簡稱服務提供商。如上文提到的github或者Google。
- User Agent:用戶代理。本文中就是指瀏覽器。
- Authorization server:授權(認證)服務器。即服務提供商專門用來處理認證的服務器。
- Resource server:資源服務器,即服務提供商存放用戶生成的資源的服務器。它與認證服務器,可以是同一臺服務器,也可以是不同的服務器。
- Access Token:訪問令牌。使用合法的訪問令牌獲取受保護的資源。
運行流程
- (A)客戶端向資源所有者請求授權。授權請求可以直接對資源所有者(如圖所示)進行,或者通過授權服務器作為中介進行間接訪問(首選方案)。
- (B)資源所有者允許授權,并返回憑證(如code)。
- (C)客戶端通過授權服務器進行身份驗證,并提供授權憑證(如code),請求訪問令牌(access token)。
- (D)授權服務器對客戶端進行身份驗證,并驗證授權憑證,如果有效,則發出訪問令牌。
- (E)客戶端向資源服務器請求受保護的資源,并通過提供訪問令牌來進行身份驗證。
- (F)資源服務器驗證訪問令牌,如果正確則返回受保護資源。
授權
從運行流程不難看出,要獲取access token必須先得到用戶授權(authorzation grant),那么如果獲取這么用戶授權呢?OAuth 2.0定義了四種類型的授權類型:
- 授權碼模式(authorization code)
- 簡化模式(implicit)
- 密碼模式(resource owner password credentials)
- 客戶端模式(client credentials)
授權碼模式(authorization code)
授權碼模式是功能最完整、使用最廣泛、流程最嚴密的授權模式。
由于這是一個基于重定向的流,所以客戶端必須能夠與資源所有者的用戶代理(通常是web瀏覽器)進行交互,并且能夠從授權服務器接收傳入的請求(通過重定向)。
- (A)用戶訪問客戶端,客戶端將用戶導向授權服務器,通過用戶代理(User-Agent)發送包括它的客戶端標識符、請求的范圍、本地狀態和一個重定向URI,授權服務器在授予(或拒絕)訪問權后將其發送給用戶代理。
- (B)授權服務器對資源所有者進行身份驗證(通過用戶代理),并確定資源所有者是否授予或拒絕客戶端的訪問請求。
- (C)假如資源所有者同意授權請求,那么授權服務器將會使用前面提供的或者事先指定的重定向URI(redirection URI),重定向到客戶端,并附上一個授權碼(code)和一個前面提供的本地狀態(state)(如果有的話,則會原值返回)。
- (D)客戶端收到授權碼,附上早先的重定向URI,向授權服務器申請令牌。這一步是在客戶端的后臺的服務器上完成的,對用戶不可見。在發出請求時,授權服務器對客戶端進行身份驗證。請求參數包含授權代碼、用于獲得驗證的授權代碼的重定向URI、標識客戶端身份的client id和client secret。
- (E)授權服務器對客戶端進行身份驗證,驗證授權代碼,并確保所收到的重定向URI與用于在步驟(C)中對客戶端重定向的URI相匹配,如果有效,授權服務器將發送訪問令牌access token和刷新令牌refresh token(可選)。
接著來介紹下各個步驟所需的參數
對于步驟A,客戶端申請授權請求的URI,包含以下參數:
- response_type授權類型。必選項,其值固定為code。
- client_id客戶端id。必選項,用于標識授權服務器中已注冊的客戶端。
- redirect_uri重定向URI。可選項,如果不填寫則使用注冊在授權服務器端與client_id對應的redirect_uri。
- scope申請的權限范圍,如read或write??蛇x項,如果申請的請求訪問超出授權服務器定義的可操作范圍則會失敗。
- state表示客戶端當前狀態??蛇x項,可以指定任意值,授權服務器會原封不動地返回這個值。
eg:
C步驟中,服務器回應客戶端的URI,包含以下參數:
- code授權碼。必選項,授權碼必須在頒發后很快過期以減小泄露風險,建議最長時間設為10分鐘,客戶端只能使用該碼一次,否則會被授權服務器拒絕。該碼與client id和重定向URI,是一一對應關系。
- state如果客戶端的請求中包含這個參數,認證服務器的回應也必須一模一樣包含這個參數。
eg:
D步驟中,客戶端向認證服務器申請令牌的HTTP請求,包含以下參數:
- grant_type許可類型(授權模式)。必選項,此處固定值為authorization_code。
- code上一步獲得的授權碼。必選項。
- redirect_uri表示重定向URI。必選項,且必須與A步驟中的該參數值保持一致。
- client_id表示客戶端ID,必選項。
eg:
E步驟中,認證服務器發送的HTTP回復,包含以下參數:
- access_token表示訪問令牌。必選項。
- token_type表示令牌類型。該值大小寫不敏感,必選項,可以是bearer類型或mac類型。
- expires_in表示過期時間,單位為秒。如果省略該參數,必須其他方式設置過期時間。
- refresh_token表示更新令牌??蛇x項,用來獲取下一次的訪問令牌。
- scope表示權限范圍。可選項,如果與客戶端申請的范圍一致,此項可省略。
eg:
簡化模式(implicit)
簡化模式(implicit grant type)不通過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了"授權碼"這個步驟,因此得名。所有步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不需要認證。具體步驟可參閱RFC6749?4.2節。
密碼模式(resource owner password credentials)
密碼模式中,用戶向客戶端提供自己的用戶名和密碼。客戶端使用這些信息,向"服務商提供商"索要授權。
在這種模式中,用戶必須把自己的密碼給客戶端,但是客戶端不得儲存密碼。這通常用在用戶對客戶端高度信任的情況下,比如客戶端是操作系統的一部分,或者由一個著名公司出品。而認證服務器只有在其他授權模式無法執行的情況下,才能考慮使用這種模式。可參閱RFC6749?4.3節。
客戶端模式(client credentials)
客戶端模式(Client Credentials Grant)指客戶端以自己的名義,而不是以用戶的名義,向"服務提供商"進行認證。嚴格地說,客戶端模式并不屬于OAuth框架所要解決的問題。在這種模式中,用戶直接向客戶端注冊,客戶端以自己的名義要求"服務提供商"提供服務,其實不存在授權問題。可參閱RFC6749?4.4節。
基于Github登錄的授權碼模式例子
前文提到了一個Github登錄留言的例子,假設我們要使用OAuth2.0協議搭建一個網站,利用Github作為授權和資源服務器,實現第三方登錄功能。
(轉載)現概況一下主要流程:
1) 網站和Github之間的協商
Github會對用戶的權限做分類比如讀取倉庫信息的權限、寫入倉庫的權限、讀取用戶信息的權限、修改用戶信息的權限等等。如果我想獲取用戶的信息,Github會要求我,先在它的平臺上注冊一個應用,在申請的時候標明需要獲取用戶信息的哪些權限,并且在申請的時候填寫你的網站域名,Github只允許在這個域名中獲取用戶信息。
此時我的網站已經和Github之間達成了共識,Github也給我發了兩張門票,一張門票叫做Client Id,另一張門票叫做Client Secret。
2)用戶和Github之間的協商
用戶進入我的網站,點擊github登錄按鈕的時候,我的網站會將Github給我的Client Id交給用戶,讓他進入Github授權界面,如果此時用戶沒有登錄,Github會提示登錄(當然這不是OAuth2.0客戶端部分應該關注的)。假設用戶已經登錄Github,那么Github看到用戶手中的門票,就知道是我的網站讓他過來的,于是就把我的網站獲取的權限擺出來,并詢問用戶是否允許網站獲取這些權限。
如果用戶同意,在授權頁面點擊了確認授權后,頁面會跳轉到我預先設定的?redirect_uri并附帶一個蓋了章的門票code。
這個時候,用戶和 Github 之間的協商就已經完成,Github 也會在自己的系統中記錄這次協商,表示該用戶已經允許在我的網站訪問上直接操作和使用他的部分資源。
3)告訴Github我的網站要來訪問
第二步中,我們已經拿到了蓋過章的門票code,但這個code?只能表明,用戶允許我的網站從github上獲取該用戶的數據,如果我直接拿這個code去github訪問數據一定會被拒絕,因為任何人都可以持有code,github并不知道code持有方就是我本人。
還記得之前申請應用的時候github給我的兩張門票么,Client Id在上一步中已經用過了,接下來輪到另一張門票Client Secret。
拿著用戶蓋過章的code和能夠標識個人身份的client_id、client_secret去拜訪 github,拿到最后的綠卡access_token。
4)用戶開始使用Github賬號在我的網站上留言
上一步github已經把最后的綠卡access_token給我了,通過github提供的 API 加綠卡就能夠訪問用戶的信息了,能獲取用戶的哪些權限在response?中也給了明確的說明,scope為user和gist,也就是只能獲取user組和gist組兩個小組的權限,user組中就包含了用戶的名字和郵箱等信息了。
?
總結
以上是生活随笔為你收集整理的OAuth2基本概念和运作流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微盟涉嫌二清,大商户模式将受理严监管
- 下一篇: npm install 时--save-