互聯網系統通常需要根據用戶身份決定是否有資源的訪問權限,這就需要對用戶進行身份認證(Authentication),驗證用戶所聲稱的身份。驗證手段通常是驗證只有用戶知道或擁有的東西,比如密碼、手機號、指紋等。
基于瀏覽器的認證
- 在沒有 JavaScript 的時代,認證由瀏覽器根據 HTTP 協議實現(約 1993 年),使用的是 HTTP Basic Authentication,登錄界面由瀏覽器自動生成,無法自定義。由于此時瀏覽器頁面無法存儲狀態,HTTP 服務端也通常只能提供無狀態服務。認證信息通過瀏覽器內核添加到 HTTP Header 中發送給服務端。
- 1994 年發明了 Cookie,使得 HTTP 服務端可以通過 Cookie 實現有狀態會話管理。此時可通過
<form>
表單提交用戶名和密碼,由服務端生成 Session 并將其標識(Session ID)存儲在 Cookie 中返回客戶端,瀏覽器在后續請求中自動攜帶該 Cookie,從而實現有狀態交互。此階段狀態由瀏覽器內核管理,頁面應用本身仍無法持久存儲狀態。
-
1995 年 JavaScript 出現后,開發者獲得了對 HTTP 請求的控制能力(例如使用 XMLHttpRequest),并能在客戶端使用本地存儲(如 LocalStorage、SessionStorage)。此時可以通過 JavaScript 控制認證流程,將 Token(如 Session ID、JWT 等)存儲并注入到請求 Header 中,實現更靈活的前端控制和單頁面應用(SPA)邏輯。
-
2012 年左右,第三方認證需求日益強烈,OAuth 2.0 架構被廣泛采用。OAuth 將原有服務端職責拆分為授權服務器(Authorization Server)、令牌端點(Token Endpoint)、資源服務器(Resource Server)。頁面應用可以通過標準的重定向流程(Authorization Code Flow 等)在無 JavaScript 環境下完成認證,并獲取訪問第三方資源的 Token。
+--------+ +---------------+| |--(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 ---| |+--------+ +---------------+Figure 1: Abstract Protocol Flow
- 隨著微服務的興起(約 2014 年以后),傳統的有狀態 Session 模式難以橫向擴展。為支持分布式系統的無狀態認證,JSON Web Token(JWT)被廣泛應用。JWT 將認證信息自包含于 Token 中,服務端無需存儲會話狀態,便可驗證請求者身份。
無瀏覽器的認證
- 2000 年左右,為支持 API 的程序化訪問,出現了 API Token 認證方式。客戶端直接將 Token(如 API Key)放入 HTTP Header(通常為 Authorization 頭)中發送,從而完成認證。此類方式無需用戶界面,適合腳本、服務間通信等非交互式場景。