前言:相信很多程序员刚接触鉴权的时候,都会有这样的困惑——Cookie和Session明明能实现登录验证,为什么还要搞个JWT?尤其是从单体应用转到分布式应用开发时,更是被这三者绕得头晕。

今天不玩专业术语堆砌,从「单体应用场景」到「分布式应用场景」,一步步讲清楚:它们各自长啥样、有什么用、为什么会出现新的方案,全程通俗比喻,新手也能一眼看懂,面试被问直接套用就行!

先给大家一个核心总览(记牢这句话,后面不迷路):Cookie是“客户端小纸条”,Session是“服务器小账本”,JWT是“客户端带签名的通行证”;三者不是替代关系,而是随着应用架构升级,适配不同场景的产物。

一、单体应用时代:Cookie + Session 就够了

在早期,我们开发的都是「单体应用」——简单说就是,整个项目的代码、数据库、服务器都在一台机器上,用户量少、请求压力小,比如一个小型企业的后台管理系统、个人博客。

这时候,Cookie和Session就是绝配,既能实现登录验证,又简单好维护。我们先分别搞懂:它们俩长啥样、有啥用。

1. Cookie:浏览器里的“小纸条”(客户端存储)

Cookie 本质就是浏览器本地存储的一小段纯文本,没有复杂结构,核心就是“键值对”,再加上一些控制参数(过期时间、域名等)。

#### ① 真实样子(浏览器里能直接看到)

打开浏览器F12→Application→Cookie,就能看到这样的内容(以百度为例):

BAIDUID=E123456789ABCDEF123456789; 
Expires=Wed, 09-Apr-2028 12:00:00 GMT; 
Path=/; 
Domain=baidu.com; 
HttpOnly

拆开看,每一部分都很简单:

  • 键值对(核心):BAIDUID=E123456789ABCDEF123456789(相当于你的“身份编号”);

  • Expires:过期时间(这里是2028年,到期后浏览器自动删除这张“小纸条”);

  • Domain+Path:控制哪些域名、哪些路径能访问这张“小纸条”(比如百度的Cookie,不会被谷歌读取);

  • HttpOnly:安全标记,禁止前端JS读取,防止被窃取(避免XSS攻击)。

#### ② 用处(核心:传递身份凭证)

Web协议本身是“无状态”的——也就是说,服务器记不住你,你第一次访问和第二次访问,服务器都以为是两个不同的人。Cookie就是用来解决这个问题的。

通俗比喻:你去小超市购物,老板给你一张写着你名字的小纸条(Cookie),你揣在兜里;下次再去,老板看到你兜里的小纸条,就知道你是老顾客,不用再重新登记。

在单体应用中,Cookie最主要的作用就是:存储SessionID,给服务器传递“我是谁”的信号(后面讲Session会细说)。除此之外,还能存一些非敏感的小数据,比如记住用户名、网页主题偏好、购物车临时数据等,因为它的大小限制在4KB左右,只能存轻量文本数据。

#### ③ 关键特点

  • 存储位置:客户端(浏览器内存或本地文件);

  • 传输方式:每次请求同一域名,浏览器自动携带,不用前端手动处理;

  • 安全性:明文存储(可加密),容易被劫持,所以不能存密码、手机号等敏感信息;

  • 生命周期:可设置(持久Cookie),不设置则关闭浏览器就失效(会话Cookie)。

2. Session:服务器里的“小账本”(服务端存储)

Session 本质是服务器端为每个用户创建的专属存储空间,里面存着用户的核心信息(比如用户ID、用户名、权限等),相当于服务器给每个用户记了一本“小账本”。

#### ① 真实样子(服务器端存储,以Redis为例)

Session不会暴露给客户端,我们只能在服务器端看到它的样子,比如用Redis存储时,数据结构如下:

{ 
  "sessionId": "sess:abc123xyz789", // 唯一标识,和Cookie里的SessionID对应 
  "value": { 
    "userId": 10086, 
    "username": "张三", 
    "role": "admin", 
    "loginTime": "2026-04-10 11:22:33", 
    "expireTime": "2026-04-10 12:22:33" // 30分钟无操作自动失效 } 
}

这里的核心是「sessionId」——它是服务器生成的唯一随机字符串,相当于“账本编号”,服务器会把这个编号交给Cookie,让Cookie带给客户端。

#### ② 用处(核心:存储用户敏感信息,实现会话管理)

为什么不把用户信息直接存在Cookie里?因为Cookie是客户端存储,不安全,容易被篡改。而Session存在服务器端,只有服务器能访问,安全性高。

结合Cookie,单体应用的登录流程(通俗版):

  1. 你输入账号密码登录,服务器验证通过;

  2. 服务器创建一本“小账本”(Session),记下你的用户信息,生成一个唯一的“账本编号”(sessionId);

  3. 服务器把“账本编号”(sessionId)写在一张“小纸条”(Cookie)上,发给浏览器;

  4. 浏览器保存这张“小纸条”,下次你访问服务器时,自动把“小纸条”带过去;

  5. 服务器拿到“账本编号”(sessionId),去查自己的“小账本”(Session),就能认出你是谁、有什么权限。

#### ③ 关键特点

  • 存储位置:服务器端(内存、Redis、数据库等);

  • 大小限制:无严格限制,取决于服务器资源,能存用户ID、权限等复杂信息;

  • 安全性:高,数据只在服务器端,客户端只存sessionId,不易被篡改;

  • 生命周期:默认30分钟左右(无操作自动失效),也能手动销毁(比如用户登出);

  • 状态:有状态——服务器必须维护所有用户的Session,记住“哪个sessionId对应哪个用户”。

3. 单体应用中:Cookie + Session 的优势与局限

#### 优势

简单、安全、好维护,适合用户量少、单台服务器的场景。比如公司内部的后台管理系统,用这套方案完全足够,开发效率高,出问题也容易排查。

#### 局限(为JWT的出现埋下伏笔)

只有一个问题:Session是“绑定服务器”的。因为Session存在单台服务器的内存/Redis里,如果这台服务器宕机,用户的Session就会丢失,用户需要重新登录;而且一旦用户量增加,单台服务器扛不住,需要多台服务器集群,Session共享就成了大难题。

二、分布式应用时代:Cookie + Session 不够用了,JWT登场

随着业务发展,用户量越来越大,单台服务器扛不住了,就需要搞「分布式应用」——简单说就是,把一个项目拆成多个服务,部署在多台服务器上(比如登录服务、订单服务、商品服务),再用负载均衡器(比如Nginx)把用户请求分发到不同的服务器上。

这时候,Cookie + Session 的短板就暴露无遗了,我们先看问题,再讲JWT怎么解决。

1. 分布式场景下,Cookie + Session 的致命问题:Session共享

举个例子:你第一次登录,负载均衡器把你的请求分发到服务器A,服务器A创建了Session(存着你的信息),并把sessionId通过Cookie发给你;第二次你再访问,负载均衡器把请求分发到服务器B,而服务器B上没有你的Session(因为Session存在服务器A上),所以服务器B不认识你,会让你重新登录。

怎么解决这个问题?有两种方案:

  • 方案1:Session同步——让所有服务器的Session互相同步,一台服务器创建Session,其他服务器都同步一份。但这种方式效率低,服务器越多,同步越慢,还容易出现数据不一致;

  • 方案2:集中存储Session——把所有服务器的Session都存在一个统一的Redis集群里,不管请求分发到哪台服务器,都去Redis里查Session。这种方式能解决问题,但会增加架构复杂度,还会依赖Redis(Redis宕机,所有用户都无法登录)。

这两种方案都不够完美,于是JWT(JSON Web Token)应运而生——它的核心优势就是「无状态」,彻底解决Session共享的问题。

2. JWT:客户端带签名的“通行证”(无状态鉴权)

JWT 本质是一段被加密签名的字符串,和Session最大的区别是:用户信息直接存在JWT里,服务器不用存任何会话数据——服务器只要验证JWT的签名,就能确认用户身份,不用查“小账本”(Session)。

#### ① 真实样子(三段式字符串,用.分隔)

JWT不像Cookie那样是简单的键值对,也不像Session那样存在服务器端,它是一段完整的字符串,长这样(可直接复制到JWT官网解码查看):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEwMDg2LCJ1c2VybmFtZSI6IuW8teS4reiLseW6lw==.Uq7ZJz9eQ5XXXXXXXXXXXXXXXXXXXXXX

拆开三段,每一段都有明确作用(不用记复杂原理,知道大概就行):

  • 第一段(头部):声明加密算法(比如HS256),告诉服务器用什么算法验证签名;

  • 第二段(载荷):存用户的核心信息(比如userId、username),是Base64编码(不是加密,能解码看到内容,所以不能存敏感信息);

  • 第三段(签名):用服务器的密钥对前两段加密生成,核心作用是防篡改——只要内容被改,签名就会失效,服务器能立刻识别。

#### ② 用处(核心:无状态鉴权,适配分布式、跨域、跨端)

通俗比喻:你去连锁超市购物,总部给你一张带盖章的通行证(JWT),通行证上写着你的名字和会员等级(载荷),盖章就是签名(防伪造);你去任何一家连锁超市(任何一台服务器),店员只要核对盖章(验证签名),就知道你是会员,不用再查总部的账本(Session)。

分布式应用中,JWT的登录流程(通俗版):

  1. 你输入账号密码登录,登录服务验证通过;

  2. 登录服务用自己的密钥,把你的用户信息(userId、username)加密签名,生成JWT;

  3. 登录服务把JWT返回给前端(前端可以存在localStorage、Cookie里,也可以放在请求头里);

  4. 你后续访问任何服务(订单服务、商品服务),都把JWT带过去;

  5. 任何一台服务器收到请求后,用相同的密钥验证JWT的签名:签名有效,就解码出用户信息,认出你是谁;签名无效,就拒绝访问。

#### ③ 关键特点

  • 存储位置:客户端(localStorage、Cookie、移动端本地等);

  • 传输方式:前端手动携带(通常放在请求头Authorization里),不依赖浏览器自动携带;

  • 安全性:中等——签名防篡改,但载荷是Base64编码(可解码),不能存敏感信息;密钥泄露会导致JWT被伪造;

  • 生命周期:签发时固定过期时间,过期前始终有效,无法主动作废(除非加黑名单);

  • 状态:无状态——服务器不用存任何会话数据,只负责验签和解码,天然适配分布式集群。

3. 分布式场景下:JWT 的优势与局限

#### 优势(解决Session的痛点)

  • 无需Session共享:服务器不用存会话数据,多台服务器随便扩容,负载均衡器随便分发请求,不用考虑Session同步问题;

  • 跨域、跨端友好:Cookie受同源策略限制,跨域时无法自动携带;JWT放在请求头里,不管是Web端、App、小程序,还是跨域服务调用,都能轻松携带;

  • 减轻服务器压力:不用查Redis/数据库获取用户信息,只要验签就能完成鉴权,性能更高;

  • 适合微服务、第三方授权:比如多个微服务之间调用,只要用同一套密钥,就能通过JWT识别用户,不用额外做Session共享。

#### 局限(不能替代Cookie + Session)

  • 不能主动作废:JWT一旦签发,在过期前始终有效,哪怕用户改密码、登出,也无法立刻让JWT失效(除非做黑名单机制,又变回有状态);

  • 信息不能太大:JWT放在请求头里,太长会导致请求头过大,影响性能;

  • 依赖密钥安全:密钥一旦泄露,任何人都能伪造JWT,冒充用户访问;

  • 不适合存敏感信息:载荷可解码,不能存密码、手机号等敏感数据。

三、三者核心对比(面试必背,一目了然)

很多人面试时被问“Cookie、Session、JWT的区别”,其实记住下面这张表,就能轻松应对,结合前面的比喻,面试官会觉得你理解得很透彻。

对比维度

Cookie

Session

JWT

本质

客户端存储的纯文本(小纸条)

服务器端的会话存储(小账本)

加密签名的身份凭证(通行证)

存储位置

客户端(浏览器)

服务器端(内存/Redis)

客户端(localStorage/Cookie等)

状态

无状态(服务器不存Cookie数据)

有状态(服务器存会话数据)

无状态(服务器不存会话数据)

核心作用

传递身份凭证(如sessionId)、存轻量非敏感数据

存储用户敏感信息、管理会话

无状态鉴权,适配分布式、跨域

分布式适配

无问题(仅传递数据)

麻烦(需Session共享)

天然适配(无状态)

跨域友好

不友好(受同源策略限制)

不友好(依赖Cookie传递sessionId)

友好(请求头携带,无限制)

主动失效

简单(浏览器删除或服务器设置过期)

简单(服务器删除Session)

困难(需黑名单机制)

适用场景

存用户名、主题偏好等轻量数据

单体应用、后台管理系统(同域名)

分布式、微服务、App、跨域、第三方授权

四、最终总结(面试满分话术+实际开发选型)

1. 面试总结(直接背)

Cookie是客户端的纯文本存储工具,核心作用是传递身份凭证(如sessionId);Session是服务器端的会话存储,核心作用是存储用户敏感信息,实现单体应用的会话管理;JWT是无状态的加密签名凭证,核心解决Session在分布式、跨域场景下的共享问题,适配微服务、跨端场景。

三者不是替代关系,而是根据应用架构选型:单体应用用Cookie+Session足够,分布式、跨端应用用JWT更合适,实际开发中也常结合使用(比如JWT存在Cookie里,利用HttpOnly提高安全性)。

2. 实际开发选型建议

  • 如果是小型单体应用(如内部后台、个人博客):用Cookie + Session,简单好维护,开发效率高;

  • 如果是分布式、微服务应用(如电商、App后端):用JWT,无需Session共享,扩容方便,跨域友好;

  • 如果是后台管理系统(同域名、用户量少):用Cookie + Session + Redis(集中存储Session),兼顾安全和可维护性;

  • 如果需要第三方授权(如微信登录、支付宝登录):用JWT,无需共享Session,第三方服务只需验签就能识别用户。

结尾

其实Cookie、Session、JWT的演进,本质是「应用架构从简单到复杂」的必然结果——从单台服务器到分布式集群,从Web端到多端适配,鉴权方案也在不断优化。

记住:没有最好的方案,只有最适合的方案。理解它们的本质、样子和适用场景,不管是面试还是实际开发,都能轻松应对。

如果觉得这篇文章对你有帮助,欢迎点赞、收藏、关注,后续会更新更多通俗易懂的后端干货!

Logo

一站式 AI 云服务平台

更多推荐