1. 程式人生 > >OAuth詳解之二:過程

OAuth詳解之二:過程

上篇文章介紹了OAuth協議大致的工作流程。本文對這個過程做個細化。

我們已經知道,客戶端在獲得資源的訪問令牌(token)前,需要獲得授權伺服器的授權。一個問題是,通訊雙方怎麼儲存這個授權的狀態呢?也就是說,伺服器給你授權了,怎麼告訴你呢?這需要一個授權碼(authorization code)。注意,這時候還沒有token。簡單地講,授權伺服器在通過資源擁有者的認證後,授權給客戶端,返回一個跳轉URI(redirect uri)。這個uri裡面包含了一個授權碼。客戶端載入這個uri,拿到授權碼,進而向授權伺服器的token元件(token endpoint)發起請求,獲得一個訪問令牌。如圖2.1所示。


下面來分析下具體的互動過程。授權伺服器在接到來自客戶端的授權請求後,會產生這樣的響應: 一個來自授權伺服器的HTTP響應header的內容如下:

狀態碼是302,即是一個重定向指令。注意其中的Location欄位,這次重定向的目標就是Location的值。response_type表示授權的型別是授權碼(code),redirect_ui欄位就是前面提到的跳轉URI,這個URI會在下次重定向用到。scope欄位定義了客戶端需要哪些授權,是一個資源訪問許可權的列表(比如讀寫許可權),以空格分隔。這個列表是資源伺服器定義的,授權伺服器在授權過程中就可以授予或拒絕特定的scope。注意此時依然沒有授權碼。接下來客戶端就會發起一個GET請求到授權伺服器獲取授權碼。


作為響應,授權伺服器依然會返回一個跳轉指令。這個響應對應的跳轉URI裡面就包含了授權碼,通常在code欄位中:


最後,客戶端再發一次GET請求。我們可以看到,這次跳轉就是不是客戶端向授權伺服器發請求了,而是直接嚮應用程式的Web伺服器發請求。這樣使用者登入的Web應用程式(無論是瀏覽器還是伺服器)就拿到了這個授權碼,留待後續使用。另外,客戶端還會檢查state欄位的值是否與上一步重定向中的state值相同。


從上面過程看出,獲取授權碼經歷了兩次重定向和兩次GET請求,目的就是讓應用程式拿到授權。可以這樣理解,第一次重定向是授權伺服器告訴客戶端你怎樣向我發起請求能拿到授權碼。那麼客戶端就按照要求發起一個GET請求。第二次重定向是伺服器告訴客戶端,授權碼在這個URI裡,你再請求一次就拿到了。於是客戶端又GET了一次,就拿到了授權碼。這就是協議的特點:雙方需要商議資訊交換的方式。 下面開始獲取訪問令牌。 客戶端這次發起一個POST請求如下:

請求中包含了Basic認證的資訊和剛剛獲得的授權碼等資訊。授權伺服器的token模組接收到這個請求後,進行了一系列的工作。首先,它要檢視Basic認證資訊,確認發起請求的客戶端是誰。為什麼這裡還需要一步認證呢?實際上,伺服器是想確認請求token的這個客戶端與剛才請求授權碼的那個客戶端是不是同一個人。如果不是,就視為非法的請求。這也合理,我授權給另一個人,你憑什麼申請token。伺服器還會檢查授權碼是否是有效的,是不是已經使用過的等等。所有這些檢查工作結束後,伺服器會返回一個token給客戶端:


注意,這裡的token型別指定為Bearer Token,為OAuth多數情況下使用的token型別,bear是承載、持有的意思,說明這個token就是請求資源所必須攜帶的。token包含客戶端的請求資訊,請求的資源資訊,授權的使用者資訊等,有關Bearer Token的詳情後面會有解讀。除了Bearer以外,伺服器還可能返回refresh token,目的是在不重新獲得授權的情況下重新整理token,這個馬上會講到。客戶端拿到token後,儲存在安全的地方,然後就可以使用它訪問伺服器資源了。通常這樣使用:


資源伺服器會解析這個請求並檢查token,看是否依然有效,查詢是誰授權的,以及授權用於做什麼,根據這些資訊進行響應。當授權伺服器生成token的時候會將其寫入資料庫,資源伺服器會到這個伺服器查詢token資訊。下面來談談token的重新整理機制。 refresh token不是用來直接請求資源的,而是用來請求新的Bearer Token的。有時因為一些原因(過期,系統內部機制,使用者回收等)會導致已有的token失效,這時需要重新獲取token。如果用失效的token請求資源,資源伺服器會返回錯誤資訊。那就需要資源擁有者重新授權然後獲取token,但你不能保證資源擁有者始終注意token的有效性。在OAuth 2.0版本里,原來的token會自動過期,然後使用refresh token請求新的Bearer Token。如圖2.10所示。
當然,如果refresh token本身失效了,就只好等待使用者重新授權了。 至此,客戶端作為使用者的代理可以正常訪問資源了。這個過程裡面其實還有很多細節值得探究,比如token是如何生成的,授權碼如何產生以及檢查的,授權伺服器如何認證使用者的等等。這些問題我會在後面文章繼續學習和分享。 如理解有誤,歡迎不吝賜教。