引言
我們在系統設計的時候,用戶的認證是最基本也是最重要的功能了。我們常見的方案,就是將用戶的認證信息保存到 session 里面。由於近年來微服務的快速興起,一種 JWT 的認證方式出現在了大眾的眼中。在單體服務的時代,很多系統設計的都是有狀態的服務。隨着微服務的出現,大多數系統設計的時候,都開始考慮無狀態服務了。那它們的唯一區別,就是服務端是否會保存客戶端的信息。簡而言之,服務端保存了客戶端的信息的這種狀態的服務,就被稱為有狀態的服務,反之,就是無狀態服務了。
有狀態
有狀態常見的模型就是 cookie - session 模型,這里就以 cookie - seesion 為例來說明有狀態服務。
用戶認證過程
1、客戶端向服務端發起請求。
2、在第一次客戶端發起請求的時候,服務端會創建一個 Key 為 session-id 的值,並保存在服務端同時寫入到客戶端的 cookie 中。
3、之后客戶端的每次請求,都會將 cookie 信息發送給服務端,服務端會根據 cookie 進行判斷。
優點
1、客戶端的信息都保存在服務端,如果將客戶端的認證信息刪除,那么只需要將對應的 session 信息刪除即可。
缺點
1、當用戶量特別大的時候,服務端需要保存大量的 session 信息,會耗費大量的資源。
2、如果在服務端集群的情況下,session 的信息不能共享。
3、cookie 有同源策略和跨域限制,部分業務場景下 cookie 不能傳遞。
4、有些瀏覽器不支持 cookie 或禁用 cookie,部分手機瀏覽器不支持 cookie。
應用場景
如果以集群式的方式部署多台服務,可以使用以下策略:
1、配置負載均衡的路由策略為 hash 一致性算法,這種方式如何某個服務停了,那么會重新分配到新的機器,就又需要重新登錄認證。(這種方式不推薦使用)
2、分布式 session 方式,這種方式可以將 session 保存到 redis 或者數據庫中,提供給多個服務使用,實現 session 的集中管理。
如果有多個服務需要共享登錄認證信息,可以使用 SSO 單點服務。
無狀態
無狀態的認證,服務端在驗證客戶端發送過來的請求信息之后,服務端根據一定的算法生成一個 Token 令牌返回給客戶端。
客戶端之后的每次請求都需要攜帶 Token 令牌,服務端接收到 Token 令牌之后進行校驗,驗證通過之后提取令牌中信息來識別用戶。
無狀態用戶認證過程
1、客戶端執行登錄操作,發送賬號密碼等信息。
2、服務端校驗客戶端的用戶信息,根據對應的用戶信息和服務端密鑰生成 Token 令牌,然后返回給客戶端。
3、客戶端在收到 Token 令牌之后,將其保存到本地的 LocalStorage。
4、以后的每次客戶端發起請求時,都攜帶 Token 令牌。
5、服務端收到 Token 令牌之后,驗證 Token 令牌的有效性和時效性,之后根據密鑰解密參數信息。
優點
1、服務端不需要保留客戶端的任何信息,每次只需要通過特定的算法進行校驗,節省了大量的存儲空間。
2、方便水平擴容,不需要 SSO 服務,只要保證新的服務采用同樣的驗證算法,就可以獲得對應的信息。
缺點
1、當客戶端的 Token 令牌被盜用,或者需要手動封禁某個用戶的時候,無法對 Token 令牌進行操作,需要等到 Token 令牌失效。
2、如果在服務端維護一個 Token 令牌和用戶的關系,又違背了無狀態服務設計的理念。
應用場景
1、生成的 Token 令牌中攜帶用戶的常用信息,不攜帶用戶的敏感信息,例如:密碼、手機號等,這些信息可以通過 BASE 64 解析處理。
2、要處理服務端主動禁用某個 Token 令牌,可以使用黑名單機制,每次請求前都判斷當前 Token 令牌是否已經被寫入黑名單。
3、Token 令牌中信息處理基本信息之外,還需要攜帶,例如:簽發時間、有效時間、刷新 Token 令牌等字段,用來處理 Token 令牌刷新過期時間。
總結
在實際的系統設計中,需要充分理解需求,合理的使用技術,不同的技術方案適用不同的場景,技術存在即合理。
其他
1、目前大部分的互聯網的產品中使用 JWT 的認證方式居多。
2、在一些企業內部的管理系統中采用 cookie - session 的居多。