Wendy Yuchen Sun

OAuth 初探

May 31, 2017

做研究時,無意間遇見 OAuth,隨手學了起來。雖然還只懂皮毛,但總是得隨時記錄下自己究竟走到哪裡,方便未來進行回顧。

順帶一提,這篇文章只能說是一個 OAuth 授權框架的大要筆記。整個實踐上有很多細節,我有閱讀相關資料與理解,但並沒有一一寫下來。我很常有這樣的感觸:許多前人已經整理出為數不少的文件,品質好,實在沒有我這個後學只是再度引述(只是為了證明我理解)的必要啊。

OAuth 是什麼?要解決什麼問題?

直言之,OAuth 是一個「授權的架構」,讓程式可以取得使用者所擁有 HTTP 服務(如臉書、推特或 GitHub)帳號有限的權限。

在 OAuth 以前,如果使用者要授權某個程式進用其 HTTP 服務帳戶,通常是透過直接給這個程式 HTTP 服務帳戶的帳號、密碼。舉例來說,某 A 要讓一個名為 someApp 的程式取得他在臉書帳戶的權限,得直接提供 someApp 他的臉書帳戶與密碼。這樣子會有一些問題,例如 someApp 可能會用明碼來儲存某 A 的臉書帳密;或是某 A 不能更動他的臉書密碼,以免 someApp 無法繼續進用某 A 的臉書帳戶。

OAuth 的出現,即希望為發展出更安全且對 HTTP 服務帳戶擁有者更為便利的授權流程。目前 OAuth 的規格出到第 2 版(OAuth 2.0)。

四種角色

在 OAuth 的架構裡,整個授權的過程中有四種角色:

一些區別

Confidential Clients v.s. Public Clients

Confidential clients 是指可以保密 client_secret 的 client 程式(什麼是 client_secret 以及其作用,後面會有說明),通常是在伺服器上跑的程式,用戶不會接觸到原始碼。Public clients 則剛好相反,是無法保密 client_secret 的 client 程式,像是跑在瀏覽器上的程式。

Access Token, Refresh Token & Authorize Code

Access token 是取得資源擁有者授權的 client 程式,用來向資源伺服器請求使用資源的字串。Refresh token 則是當 access token 過期後,client 程式用來請求新的 access token 用的。

Authorization code 則是 confidential clients 取得授權過程中的中介,這類 clients 在取得資源擁有者授權後,會獲得 authorization code,再用 authorization code 交換 access token。

不同類型的授權路徑 - 依據客戶端程式區分

無論是哪一種類型的客戶端程式,都要先向 HTTP 服務註冊,產生 client_id,若是 confidential clients 還會產生只有授權伺服器與客戶端知道、資源擁有者不知道,類似客戶端對授權伺服器密碼的 client_secret

Sever-side Apps

如前面所述,這是可以隱藏 client_secret 的客戶端程式,整個授權的流程大致如下:

  1. 客戶端程式引導資源擁有者到授權伺服器提供授權的介面,通常這個界面的 URL 會包含幾個參數:客戶端在註冊時產生的 client_id、希望收到的 response_type(在這種類型裡是 code,因為之後希望收到 authorization code),以及其他可選用的參數:redirect_uriscopestate 等等。
  2. 資源擁有者授權客戶端後,授權伺服器會引導資源擁有者到客戶端提供的 redirect_uri,並在這個 URL 裡附上 authorization code。
  3. 客戶端向授權伺服器取得 access token 的介面發出 POST 請求,並附上 authorization code、希望獲取的 grant_type,以及其他授權伺服器要求的資訊,如 client_idclient_secret
  4. 授權伺服器回傳 access token、refresh token 等能讓客戶端向資源伺服器請求使用帳戶或帳戶資訊的 token。

Browser-based & Mobile Apps

這兩類都是無法隱藏 client_id 的客戶端,所以跳過了客戶端利用 authorization code 交換 access token 的步驟,客戶端直接向授權伺服器取得 access token。步驟大致如下:

  1. 客戶端程式引導資源擁有者到授權伺服器提供授權的介面,通常這個界面的 URL 會包含幾個參數:客戶端在註冊時產生的 client_id、希望收到的 response_type(在這種類型裡是 token,因為之後希望直接收到 access token,這是與前面 sever-side apps 的授權流程不同之處),以及其他可選用的參數:redirect_uriscopestate 等等。
  2. 資源擁有者授權客戶端後,授權伺服器會引導資源擁有者到客戶端提供的 redirect_uri,並在這個 URL 裡附上可以讓客戶端程式向資源伺服器請求使用帳戶或帳戶資訊的 access token。

References

其中 OAuth.com 的背景章節,大略介紹了整個 OAuth Framework 產生的歷程、社群互動狀況的衍變,以及目前的處境/困境。對於這類枝節,我總覺得十分有趣。附帶一提,除了有趣的枝節外,這個網站對於 OAuth 的實作也記載地十分詳實,包含了很多我有去了解但沒有寫在這篇大要記錄裡的細節。

P.s.

我在最後想起 kamranahmedse 的 “Web Developer Roadmap - 2017”,裡頭在後端的部分,提到 Authentication 裡有 OAuth2 以及 JSON web token(JWT)。原來我在整棵後端技術樹的這裡!看來除了繼續深究 OAuth,另一條可以走走看的小徑是 JWT,期待未來的新旅程。

Comment is free.