1. 簡介
OAuth(開放授權)是一個開放標準,允許使用者讓第三方應用訪問該使用者在某一網站上儲存的私密的資源(如照片,視訊,聯絡人列表),而無需將使用者名稱和密碼提供給第三方應用。因此OAUTH是安全的。OAuth是Open Authorization的簡寫。
而OAuth2.0是OAuth協議的下一版本,但不向後相容OAuth 1.0。 OAuth 2.0關注客戶端開發者的簡易性,同時為Web應用,桌面應用和手機,和起居室裝置提供專門的認證流程。2012年10月,OAuth 2.0協議正式釋出為RFC 6749 。
2. 認證過程
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
上圖中所涉及到的物件分別為:
- Client 第三方應用,我們訪問的應用就是一個Client。
- Resource Owner 資源所有者,即使用者。
- Authorization Server 授權伺服器,即提供第三方登入服務的伺服器,如Github。
- Resource Server 擁有資源資訊的伺服器,通常和授權伺服器屬於同一應用。
根據上圖的資訊,我們可以知道OAuth2的基本流程為:
- 第三方應用請求使用者授權。
- 使用者同意授權,並返回一個憑證(code)
- 第三方應用通過第二步的憑證(code)向授權伺服器請求授權
- 授權伺服器驗證憑證(code)通過後,同意授權,並返回一個資源訪問的憑證(Access Token)。
- 第三方應用通過第四步的憑證(Access Token)向資源伺服器請求相關資源。
- 資源伺服器驗證憑證(Access Token)通過後,將第三方應用請求的資源返回。
3. 例項
看完OAuth的基本流程後,大家實際上對到底如何做OAuth驗證還是不太清楚,同時,也會產生疑問,為什麼需要兩次獲取憑證,而不是直接使用者授權拿到憑證後就直接獲取資源呢?這和OAuth的具體實現有關,讓我們來看看OAuth2的具體實現吧。
我們以CSDN為例。
3.0 訪問登陸頁面
當用戶希望使用第三方登入進行登入時,第三方應用會通過類似下圖"快速登陸圖示"的方式將使用者引導至授權頁面,為了和OAuth基本流程一致,我們將這一步定義為第0步。
3.0.5 使用者身份驗證
當我們點選Github的圖示,我們會進入到Github應用下面,此時實際上進行了一次使用者身份的驗證,之前沒有登入Github的使用者需要輸入Github的賬號密碼,已登入的使用者Github會根據Session進行身份確認。此操作我們稱為0.5步。接下來正式進入OAuth2的流程。
3.1 使用者授權
使用者身份確認後會進入下面這個頁面,該頁面由授權伺服器提供,授權伺服器會告訴使用者該第三方在授權伺服器中提交的相關資訊(如果需要實現第三方登入功能,第三方應用需要向Github、微博等應用中提交應用的相關資訊,不同服務可能會需要稽核等不同的步驟),以及授權後第三方應用能夠獲取哪些資源。在Github中,最基礎的認證可以訪問使用者的公共資訊。如果使用者同意授權,需要主動的點選【Authorize application】按鈕。
3.2 返回使用者憑證(code)
當用戶點選按鈕同意授權後,授權伺服器將生成一個使用者憑證(code),此時授權伺服器如何將使用者憑證(code)傳遞給第三方應用呢?
當我們向授權伺服器提交應用資訊時,通常需要填寫一個redirect_uri,當我們引導使用者進入授權頁面時,也會附帶一個redirect_uri的資訊(如Sign in to GitHub · GitHub),當授權伺服器驗證兩個URL一致時,會通知瀏覽器跳轉到redirect_uri,同時,在redirect_uri後附加使用者憑證(code)的相關資訊,此時,瀏覽器返回第三方應用同時攜帶使用者憑證(code)的相關資訊。授權後訪問的redirect_uri如下:
https://www.csdn.net/oauth/github/callback?code=9e3efa6cea739f9aaab2&state=XXX
這樣,第二步返回使用者憑證(code)就完成了。
3.3 請求授權伺服器授權
從這一步開始,OAuth2 的授權將有兩個重大變化的發生:
- 使用者主動行為結束,使用者理論上可以不需要再做任何主動的操作,作為第三方應用的我們可以在後臺拿到資源伺服器上的資源而對使用者是不可見的,當用戶的瀏覽器跳到下一個頁面時,整個OAuth2的流程已經結束
- 瀏覽器端行為結束,從OAuth2 的基本流程可以看出,接下來的流程已經不需要和使用者進行互動,接下來的行為都在第三方應用與授權伺服器、資源伺服器之間的互動。
我們知道瀏覽器端的行為實際上是不安全的,甚至安全憑證的傳遞都是通過URL直接傳遞的。但是由於使用者憑證(code)不是那麼敏感,其他攻擊者拿到使用者憑證(code)後依然無法獲取到相應的使用者資源,所以之前的行為是允許的。接下來我們看看伺服器如何互動來安全的獲得授權伺服器授權。
要拿到授權伺服器的授權,需要以下幾個資訊:
- client_id 標識第三方應用的id,由授權伺服器(Github)在第三方應用提交時頒發給第三方應用
- client_secret 第三方應用和授權伺服器之間的安全憑證,由授權伺服器(Github)在第三方應用提交時頒發給第三方應用
- code 第一步中返回的使用者憑證redirect_uri 第一步生成使用者憑證後跳轉到第二步時的地址
- state 由第三方應用給出的隨機碼
我們看到,上述資訊還涉及到第三方應用的安全憑證(client_secret),因此要求OAuth要求該請求必須時POST請求,同時,還必須時HTTPS服務,以此保證獲取到的驗證憑證(Access Token)的安全性。
3.4 返回訪問憑證(Access Token)
當授權伺服器拿到第3步中的所有資訊,驗證通過後,會將Access Token返回給第三方應用。
3.5 向資源伺服器請求相關資源
拿到驗證憑證(Access Token)後,剩下的事情就很簡單了,資源伺服器會提供一系列關於使用者資源的API,拿驗證憑證(Access Token)訪問相應的API即可,例如,在Github中,如果你想拿到使用者資訊,可以訪問以下API:
GET https://api.github.com/user?access_token=...
注意,此時的訪問不是通過瀏覽器進行的,而是伺服器直接傳送HTTP請求,因此其安全性是可以保證的。
3.6 返回資源
如果驗證憑證(Access Token)是正確的,此時資源伺服器就會返回資源資訊,此時整個OAuth流程就結束了。