HTTP 無狀態
由於 HTTP 是一個無狀態協議,也就是說,Shopper 每次對 Server 發出的請求都是獨立的,Server 並不會記住 Shopper 所發出的每個請求及其資訊,因此無法辨識上一次與這一次的訪問者身份是否為同一人,然而我們可以透過 Cookie 或 Session 等機制來判斷每一次發送的請求其身份以及當前使用者的登入狀態等資訊。
Cookie 和 Session 的區別
-
安全性: Session 比 Cookie 安全,Session 是存儲在 Server 端的,Cookie 是存儲在 Shopper 端的。
-
存取值的類型不同:Cookie 只支持存字符串數據,想要設置其他類型的數據,需要將其轉換成字符串,Session 可以存任意數據類型。
-
有效期不同: Cookie 可設置為長時間保持,比如我們經常使用的默認登錄功能,Session 一般失效時間較短,客戶端關閉(默認情況下)或者 Session 超時都會失效。
-
存儲大小不同: 單個 Cookie 保存的數據不能超過 4K,Session 可存儲數據遠高於 Cookie,但是當訪問量過多,會佔用過多的服務器資源。
Shopper 訪問 Server 流程
Session ID 是連接 Cookie 和 Session 的一道橋樑
(使用者首次登入帳密時)
- 首先,Shopper 端會發送一個 Http 請求到 Server 端。
- Server 端接受 Shopper 端請求後,會在 Server 端建立 Session,並提供 Shopper 端相對應的 Session ID,這個 Session ID 將存放於 Response Headers 的 set-cookie 欄位。格式如下:
Set-Cookie: sessionId=xxx; expires=xxx; path=/;....
(往後來自 Shopper 端的請求)
- 之後的使用者在每一次登入時都會拿 Cookie 的資料去跟後端核對使用者身份,也就是說,Server 會以 Cookie 中 Session ID 尋找 Session 確認使用者驗證狀態。
這意味著…
每位使用者經過驗證後,都需要為其建立和存取 Session(可能在DB中)然而:
a. 當使用者量增加,資料庫的花費成本將不斷提高。
b. 每當使用者拜訪需經驗證的路徑時,也需要額外到資料庫執行資料查詢,花費額外的效能。
JSON Net Token(JWT)也因此誕生,它更符合設計 RESTful API 時「Stateless 無狀態」原則:意味著每一次從客戶端向伺服器端發出的請求都是獨立的,使用者經驗證後,在伺服器端不會將用戶驗證狀態透過 Session 儲存起來,因此每次客戶端發出的請求都將帶有伺服器端需要的所有資訊 — 從客戶端發出給伺服器端的請求將帶有 JWT 字串表明身份 。
JSON Net Token(JWT)
是一種認證授權機制。
作用:驗證使用者身分,並可跨域獲取資源的作法
特性:
– Stateless 無狀態
– 安全
JWT 與 Token 唯一不同的是:
-
Token:Server 驗證 Shopper 發送過來的 Token 時,還需要查詢數據庫獲取用戶信息,然後驗證 Token 是否有效。
-
JWT: 將 Token 和 Payload 加密後存儲於 Shopper 端,Server 只需要使用密鑰解密進行校驗(校驗也是 JWT 自己實現的)即可,不需要查詢或者減少查詢數據庫,因為 JWT 自包含了用戶信息和加密的數據。
有了 Token 之後
- 使用者登入,成功後,伺服器返回 Token。
- Shopper 收到 Token 後,將 Token 存進 Cookie。
- 往後使用者再次登入時,瀏覽器將自動把 Cookie(JWT) 存放於 Request Headers 的
authorization
欄位。格式如下:
- Server 接受請求,解析並驗證 Cookie,核對成功後返回 Response 給 Shopper 端。
總結:
基於 Token 的用戶認證是一種 Server 端無狀態的認證方式,Server 不用存放 Token 數據。用解析 Token 的計算時間換取 Session 的存儲空間,從而減輕服務器的壓力,減少頻繁的查詢數據庫。