最開始接觸 OAuth2.0 的時候,經常將它和 SSO單點登入搞混。後來因為工作需要,在專案中實現了一套SSO,通過對SSO的逐漸瞭解,也把它和OAuth2.0區分開了。所以當時自己也整理了一篇文章《SSO單點登入原理及實現方式》
最近需要經常和各大電商平臺進行對接,所以又和OAuth2.0重逢了。因此這裡再次對OAuth2.0的原理及實現方式進行一個梳理,希望通過這套教程能夠幫到大家。對於技術類的文章,這引言是有點過長了。好了下面我們進入正題。
什麼是 OAuth2.0
OAuth 是一種開放的授權協議,它是目前最流行的授權機制。它允許將儲存在一個站點上的資源共享到另一個站點,而無需使用該站點的憑據。
這類定義一般都比較抽象,要理解起來不是太容易。所以這裡我們通過一個實際應用的類比來說明一下這個場景,你會發現,其實OAuth2.0的原理並不複雜。
首先,假設我在微信上註冊了賬號,然後加了一些好友,並且有一些聊天記錄。
然後,我正在訪問一個網站/應用。這裡假設正在訪問 www.jiyik.com 。這個網站有一項功能是可以獲取微訊號上的好友和聊天,然後對這些資訊進行一個統計分析的功能(當然,本站是沒有這項功能的)。
個人感覺這項功能不錯,就想使用它。有一種方式是我可以把個人的微信賬號和密碼告訴這個應用。應用可以通過賬號密碼獲取到好友資訊和聊天記錄。但是這樣我感覺很不安全,如果我以後不想再繼續使用了,那我還得再去修改賬號和密碼。那樣就會很麻煩了。所以這裡就需要一種方式可以使得我將一些許可權授權給該網站,使其可以不用賬號和密碼就可以獲取到這些資訊。 這種授權方式就是 OAuth2.0。當我不再想使用該功能的時候,我就可以把許可權收回或者使授權失效。
所以說一個完整的OAuth2.0 的流程需要涉及到三個實體。
- 資源服務商 (微信,Google,Facebook等)
- 第三方網站/應用
- 使用者
當有另一個第三方的網站要使用微信賬號登入其系統時,同樣我們也可以通過授權的方式登入這個第三方的網站。這樣就實現了同一個微信賬號可以多個不同的網站進行登入。這也是一種單點登入,這也是為什麼最初經常會將其和SSO單點登入搞混的原因。
通過上面的場景,我們大概也能清楚OAuth2.0的基本的原理了。下面我們通過整體介紹一下其架構,來更深入的瞭解其工作原理。
OAuth2.0 架構
整個的流程是這樣的。
一、 首先,使用者使用 Google、微信 等第三方應用程式訪問資源。
二、 第三方網站會帶著客戶端ID和客戶端金鑰重定向到資源服務的授權登入介面。
三、 使用者會接收到一個Google或微信的授權登入介面。使用者需要在該介面進行授權。
四、 使用者使用身份驗證應用程式登入。客戶端 ID 和客戶端金鑰對於授權伺服器上的客戶端應用程式是唯一的。
五、 身份驗證伺服器使用授權程式碼將使用者重定向到重定向統一資源識別符號 (URI)。這個地址是第三方網站在接入資源服務的認證服務時提交給認證服務的,當使用者授權成功後,會被重定向到該網址。
六、 使用者訪問位於客戶端應用程式中重定向 URI 的頁面,該頁面此時會帶有一個用於驗證的Code。
七、 客戶端應用程式將獲得身份驗證Code、客戶端 ID 和客戶端金鑰,並將它們傳送到授權伺服器。
八、 身份驗證應用程式向客戶端應用程式返回訪問令牌。
九、 一旦客戶端應用程式獲得訪問令牌,使用者開始使用客戶端應用程式訪問資源所有者的資源。
整個OAuth2.0的流程就是這樣的。這其中會涉及到一些HTTP的知識點,關於HTTP可以參考我們的 HTTP教程。
OAuth2.0會涉及到很多術語和概念,下面我們對這些術語概念進行一些解釋。
術語
驗證
身份驗證是識別一個使用者的過程,通常是基於使用者個人的使用者名稱和密碼。通過使用者名稱和密碼來驗證該使用者是否是一個合法的資源持有者。
聯合身份驗證
許多第三方網站/應用都有自己的使用者名稱和密碼。某些應用程式依賴於其他服務來驗證使用者的身份。聯合身份管理系統提供對多個系統的單一訪問。這稱為聯合身份驗證。
授權
授權是允許某人做某事的過程。它需要有效使用者的身份來檢查該使用者是否被授權。
委託授權
委託授權是將自己的憑據提供給其他使用者以代表該使用者執行某些操作的過程。
角色
OAuth 定義了以下角色
- 資源所有者 - 資源所有者被定義為能夠授予訪問其在資源伺服器上託管的自己資料的能力的實體。當資源所有者是個人時,稱為終端使用者。
- 客戶端應用程式 - 客戶端是一個應用程式,它發出受保護的資源請求以代表資源所有者執行操作。
- 資源伺服器 - 資源伺服器是可用於訪問使用者資訊的 API 伺服器。
- 認證伺服器 - 認證伺服器從資源所有者那裡獲得許可並將訪問令牌分發給客戶端,以訪問由資源伺服器託管的受保護資源。
Web 伺服器
Web 伺服器是一個計算機系統,它使用 HTTP協議 將網頁傳送給使用者。只要應用程式想要訪問資源伺服器,客戶端ID和金鑰就儲存在web應用程式伺服器上。將客戶端ID和金鑰儲存在 Web 應用程式伺服器上的目的是保密。
在上圖中,資源所有者允許機密客戶端訪問託管在資源伺服器上的資料,其中客戶端 ID 和金鑰儲存在伺服器上並且是保密的。
客戶端 ID 和金鑰對於授權伺服器上的客戶端應用程式是唯一的。
資源伺服器是一個伺服器,它承載著 Google、微信等資源。這些資源儲存在資源伺服器上,供客戶端應用程式訪問,資源所有者擁有這些資源。
然後,授權伺服器使用客戶端 Web 應用程式訪問資源所有者的資源。
使用者代理
使用者代理應用程式由使用者裝置中的客戶端應用程式使用,它可以是一個指令碼語言,例如在瀏覽器中執行的 JavaScript。所以說我們可以將使用者代理應用程式儲存在 Web 伺服器上。
下圖顯示了客戶端使用者代理應用程式的架構。
一、 首先,使用者使用 Google、微信 等身份驗證應用程式訪問資源所有者的資源。
二、 接下來,使用者應用程式提供客戶端 ID 和客戶端金鑰,從而登入到授權伺服器。
三、 然後,使用者代理應用程式提供一個在瀏覽器中執行的 JavaScript 應用程式例項並連結到 Web 伺服器。
四、 授權伺服器允許使用客戶端憑據從資源伺服器訪問資源。
五、 資源伺服器包含由資源所有者擁有的資源。
本機應用程式
本機應用程式可以用作桌面或手機應用程式的例項,它使用資源所有者憑據。它是安裝在資源所有者裝置上的客戶端應用程式。
應用程式使用的身份驗證憑據包含在應用程式程式碼中。因此,不要使用在外部使用者代理中執行的本機應用程式。
一、 首先,使用者使用 Google、微信 等身份驗證應用程式訪問資源所有者的資源。
二、 接下來,本機應用程式使用客戶端 ID 和客戶端金鑰登入到授權伺服器。本機應用程式是桌面或手機應用程式的例項,它安裝在使用者計算機上,並將客戶端金鑰儲存在計算機或裝置上。
三、 授權伺服器允許使用客戶端憑據從資源伺服器訪問資源。
四、 資源伺服器包含由資源所有者擁有的資源。
總結
以上我們介紹了OAuth2.0 的整體流程,以及這中間涉及到的一些術語和概念我們分別進行了介紹。這要求我們對 HTTP協議 的原理要稍微有些瞭解。通過上面的介紹其實我們可以看到,整個過程較為核心的部分就是對 訪問令牌的獲取。