Session和JWT的區(qū)別是什么以及與Cookie相比詳解

1. 引言:兩張“入場券”的不同命運(yùn)
想象你去參加一場大型音樂節(jié)。入口處有兩種入場方式:一種是工作人員給你一張編號卡片(Session ID),然后在后臺系統(tǒng)里記錄你的姓名、年齡、VIP等級(Session 數(shù)據(jù))。你每次進(jìn)出,工作人員只需要核對卡片編號,系統(tǒng)里調(diào)出你的信息。另一種方式是發(fā)給你一張加密手環(huán)(JWT),手環(huán)里直接寫入了你的姓名、VIP等級和有效期,工作人員掃描手環(huán)就能驗(yàn)證身份,后臺不需要記錄任何信息。
第一種方式就像傳統(tǒng)的 Session,有狀態(tài)、可控制、但需要后臺系統(tǒng)“記住”每個人;第二種方式就像 JWT,無狀態(tài)、輕量、但一旦發(fā)出就難以收回。本文將從最基礎(chǔ)的概念講起,深入對比 Session 和 JWT 的機(jī)制、優(yōu)缺點(diǎn),幫你做出正確的技術(shù)選型。
2. 前置知識:為什么需要狀態(tài)管理?
HTTP 協(xié)議是無狀態(tài)的——服務(wù)器不會記住兩次請求之間的關(guān)系。為了讓服務(wù)器能認(rèn)出“你是誰”,我們需要一種機(jī)制來維持狀態(tài)。Session 和 JWT 是兩種主流解決方案,但它們的實(shí)現(xiàn)哲學(xué)截然不同。
3. 核心定義
| 概念 | 定義 | 狀態(tài)性 |
|---|---|---|
| Session | 服務(wù)端為每個用戶創(chuàng)建的會話對象,數(shù)據(jù)存儲在服務(wù)器端(內(nèi)存/Redis/數(shù)據(jù)庫),通過唯一的 Session ID(通常存于 Cookie)關(guān)聯(lián)客戶端。 | 有狀態(tài)(服務(wù)端存儲) |
| JWT | 一種緊湊的、自包含的 JSON 對象,通過數(shù)字簽名保證完整性,用于在客戶端和服務(wù)器間安全傳遞聲明(如用戶身份信息),無需服務(wù)器存儲狀態(tài)。 | 無狀態(tài)(客戶端存儲) |
Cookie 的角色:Cookie 是載體,而非會話機(jī)制本身。Session 將 Session ID 存于 Cookie,JWT 也可以存于 Cookie(或 localStorage)。
4. 工作機(jī)制詳解
4.1 Session 工作流程

4.2 JWT 工作流程

5. 核心對比表
| 維度 | Session | JWT |
|---|---|---|
| 狀態(tài)性 | 服務(wù)端有狀態(tài),需集中存儲(如 Redis) | 服務(wù)端無狀態(tài),Token 自包含 |
| 存儲位置 | Session ID 在 Cookie;數(shù)據(jù)在服務(wù)端 | Token 存于客戶端(Cookie / localStorage) |
| 服務(wù)器資源 | 占用服務(wù)器內(nèi)存/Redis(用戶越多資源消耗越大) | 無存儲開銷,僅驗(yàn)證簽名 |
| 安全性 | Session ID 可設(shè)置 HttpOnly 防 XSS;需防 CSRF | 若存 localStorage 易被 XSS 竊??;簽名防篡改但內(nèi)容可解碼 |
| 實(shí)時吊銷 | ? 支持(session.invalidate()) | ? 困難,需維護(hù)黑名單(增加狀態(tài)) |
| 分布式擴(kuò)展 | 需共享存儲(如 Redis 集群) | ? 天然支持,無需共享存儲 |
| 跨域支持 | 依賴 Cookie,需配置 CORS 和 withCredentials | ? 通過請求頭攜帶,不受同源策略限制 |
| 過期控制 | 基于最后訪問時間的空閑超時(如 30 分鐘無操作) | 簽發(fā)時固定過期時間(exp 聲明),無法自動延長 |
| 數(shù)據(jù)大小 | Session ID ?。ㄍǔ资止?jié)) | JWT 大小隨 payload 增長(通常幾百字節(jié)到幾KB) |
| 典型載體 | Cookie(HttpOnly) | Cookie / localStorage / 請求頭 |
6. 原理分析:為什么 JWT 是無狀態(tài)的?
Session 的本質(zhì)是服務(wù)端存儲數(shù)據(jù),客戶端只知道一個“鑰匙”(Session ID)。這意味著服務(wù)端必須維護(hù)一個“鑰匙 ↔ 數(shù)據(jù)”的映射表,因此是有狀態(tài)的。
JWT 的本質(zhì)是把用戶信息直接寫入令牌,通過數(shù)字簽名保證令牌未被篡改。服務(wù)器收到 JWT 后,只需驗(yàn)證簽名(無需查詢數(shù)據(jù)庫),就能信任其中的內(nèi)容,因此是無狀態(tài)的。
JWT 結(jié)構(gòu)(三部分): header.payload.signature 示例:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywiZXhwIjoxNzQzMTU4ODAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
簽名原理:signature = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)。服務(wù)器使用同樣的密鑰驗(yàn)證簽名,確保令牌未被篡改。
7. 安全風(fēng)險與防護(hù)措施
| 機(jī)制 | 主要風(fēng)險 | 防護(hù)措施 |
|---|---|---|
| Session | XSS 竊取 Session ID;CSRF 利用自動攜帶 | HttpOnly(防 XSS)、SameSite=Strict/Lax(防 CSRF)、Secure(僅 HTTPS)、Session ID 定期刷新 |
| JWT | XSS 竊取(若存 localStorage);簽名密鑰泄露;無法主動吊銷 | 存 HttpOnly Cookie(防 XSS)、短過期時間(如 15 分鐘)+ Refresh Token、強(qiáng)密鑰、敏感信息不入 payload |
8. 適用場景與選型建議
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 傳統(tǒng)單體 Web 應(yīng)用 | Session + Cookie | 實(shí)現(xiàn)簡單,支持實(shí)時吊銷,用戶狀態(tài)易管理 |
| 前后端分離(SPA) | JWT + HttpOnly Cookie | 無狀態(tài),跨域友好,兼顧安全 |
| 微服務(wù)架構(gòu) | JWT | 無需共享 Session 存儲,服務(wù)間調(diào)用便利 |
| 移動端 / 原生 App | JWT | 不依賴 Cookie,通過請求頭傳遞 |
| 第三方開放 API | JWT / OAuth2 | 無狀態(tài),適合給第三方應(yīng)用簽發(fā)令牌 |
| 需要強(qiáng)制踢人 / 實(shí)時注銷 | Session | 服務(wù)端可直接刪除 Session |
| 高并發(fā)、需水平擴(kuò)展 | JWT + Redis 黑名單(可選) | 無狀態(tài)擴(kuò)展容易,黑名單解決吊銷問題 |
9. 常見誤區(qū)
| 誤區(qū) | 正解 |
|---|---|
| “JWT 比 Session 更安全” | ? 安全性取決于實(shí)現(xiàn)。Session 有 HttpOnly 護(hù)身,JWT 若存 localStorage 反而不安全。 |
| “Session 必須用 Cookie” | ? Session ID 可通過 URL 重寫傳遞,但體驗(yàn)與安全性差,極少使用。 |
| “JWT 可以無限期有效” | ? 必須設(shè)置短期過期時間,配合 Refresh Token 機(jī)制。 |
| “JWT 的 payload 可以存密碼” | ? payload 是 Base64 編碼,可解碼,絕對不能存敏感信息。 |
| “用了 JWT 就完全無狀態(tài)” | ? 若要實(shí)現(xiàn)吊銷,仍需引入黑名單等有狀態(tài)機(jī)制。 |
10. 總結(jié):一張圖看懂選型

| 維度 | Session | JWT |
|---|---|---|
| 控制力 | ????? 強(qiáng)(可實(shí)時吊銷、審計(jì)) | ?? 弱(難以吊銷) |
| 擴(kuò)展性 | ?? 需共享存儲 | ????? 天然無狀態(tài) |
| 跨域友好 | ?? 依賴 Cookie 配置 | ????? 請求頭傳遞 |
| 實(shí)現(xiàn)復(fù)雜度 | ?? 簡單(框架內(nèi)置) | ??? 需管理過期、刷新 |
最終建議:
- ? 內(nèi)部管理后臺、傳統(tǒng)單體應(yīng)用 → Session
- ? 前后端分離、微服務(wù)、移動端 API → JWT + 短期過期 + Refresh Token
- ? 高安全場景 → Session + Redis(有狀態(tài))+
HttpOnlyCookie - ? 追求極簡擴(kuò)展 → JWT(無狀態(tài))
沒有絕對“更好”的技術(shù),只有“更合適”的選擇。理解 Session 和 JWT 的本質(zhì)差異,才能在架構(gòu)設(shè)計(jì)時做出正確決策。
到此這篇關(guān)于Session和JWT的區(qū)別是什么以及與Cookie相比詳解的文章就介紹到這了,更多相關(guān)Session、JWT與Cookie相比內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IntelliJ IDEA之高效代碼插件RainBow Brackets詳解
這篇文章主要介紹了IntelliJ IDEA之高效代碼插件RainBow Brackets詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
Java給JFrame窗口設(shè)置熱鍵的方法實(shí)現(xiàn)
這篇文章主要介紹了Java給JFrame窗口設(shè)置熱鍵的方法實(shí)現(xiàn),文中通過示例代碼以及圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
OpenTelemetry初識及調(diào)用鏈Trace詳解
這篇文章主要為為大家介紹了OpenTelemetry初識及調(diào)用鏈Trace詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
在springboot中注入FilterRegistrationBean不生效的原因
這篇文章主要介紹了在springboot中注入FilterRegistrationBean不生效的原因及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
SpringBoot實(shí)現(xiàn)短信發(fā)送及手機(jī)驗(yàn)證碼登錄
本文主要介紹了SpringBoot實(shí)現(xiàn)短信發(fā)送及手機(jī)驗(yàn)證碼登錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Java基礎(chǔ)將Bean屬性值放入Map中的實(shí)例
這篇文章主要介紹了Java基礎(chǔ)將Bean屬性值放入Map中的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-07-07
SpringBoot Security密碼加鹽實(shí)例
這篇文章主要為打擊介紹了SpringBoot Security密碼加鹽實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
基于SpringBoot解決CORS跨域的問題(@CrossOrigin)
這篇文章主要介紹了基于SpringBoot解決CORS跨域的問題(@CrossOrigin),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
Java使用HttpUtils實(shí)現(xiàn)發(fā)送HTTP請求
這篇文章主要介紹了Java使用HttpUtils實(shí)現(xiàn)發(fā)送HTTP請求,HTTP請求,在日常開發(fā)中,還是比較常見的,今天給大家分享HttpUtils如何使用,需要的朋友可以參考下2023-05-05

