一文详解Token,Session,Cookie和JWT的区别

文章详细介绍了HTTP协议的无状态特性以及为保持状态而引入的各种技术,包括Cookie的作用、特点和应用场景,Session的原理、优缺点,以及Token和JWT在身份验证和跨域问题上的解决方案。文中还对比了Session和Cookie、JWT和Session的区别,强调了JWT在扩展性和安全性上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

作用

特点

应用场景

Session

 特点

Session和Cookie的对比

不足

Token

特点

JWT

作用

内容

使用场景

JWT和Session的对比

JWT的安全风险及防范措施

一、JWT的安全风险

二、防范措施

三、扩展实践

解决跨域问题

Session持久化

JWT方案


背景

为了提高协议的可扩展性和灵活性,确保它可以适用于各种不同的应用场景,并且为了减轻服务器的负担,使其更加轻量级. HTTP是无状态的,在每次服务端接收到客户端的请求时,都会是个全新的请求,服务器并不知道这个请求是谁发起的,也不知道这个请求是不是第一次发起的,也不知道这个请求是不是最后一次发起的。这就意味着,每次请求都是独立的,服务器不会记录任何请求的信息,也不会记录任何客户端的信息。那么如何实现状态维持的呢?

简单来说,服务器可以给你发个通行证,这样你可以拿着通行证,在这个网站里到处逛。因此,诞生了这一系列的设计,从网景公司发明的 Cookie,到后来Session、LocalStorage、IndexDB 等技术,都为客户端处理状态信息提供了很多的解决方案。

Cookie是浏览器实现的一种数据存储技术。一般由服务器生成,发送给浏览器(客户端也可进行Cookie设置)进行存储,下一次请求同一网站时会把该Cookie发送给服务器。

作用

  • 会话管理:登陆、购物车、游戏得分或者服务器应该记住的其他内容
  • 个性化:用户偏好、主题或者其他设置
  • 追踪:记录和分析用户行为

特点

  • Cookie存储在客户端(浏览器),发送请求时自动携带放在请求头中。
  • Cookie只能以文本的方式保存字符串类型的数据。
  • 单个Cookie保存的数据不能超过4KB
  • Cookie的安全性不高,别人可以分析存放在本地的Cookie并进行Cookie欺骗。
    • Cookie 劫持
    • XSS 攻击
  • Cookie默认不可跨域,可通过特殊的操作如:设置withCredentials属性为true实现跨域。

应用场景

  • 在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了。除此之外,Cookie 还能保存用户首选项,主题和其他设置信息。
  • 使用Cookie 保存 Session 或者 Token ,向后端发送请求的时候带上 Cookie,这样后端就能取到session或者token了。这样就能记录用户当前的状态了,因为 HTTP 协议是无状态的。
  • Cookie 还可以用来记录和分析用户行为。例如在网上购物的时候,因为HTTP协议是没有状态的,如果服务器想要获取你在某个页面的停留状态或者看了哪些商品,一种常用的实现方式就是将这些信息存放在Cookie

Session

Session 是另一种记录服务器和客户端会话状态的机制,并且Session 是基于 Cookie 实现的。服务器要知道当前请求发给自己的是谁,为了做这种区分,服务器就是要给每个客户端分配不同的"身份标识",然后客户端每次向服务器发请求的时候,都带上这个“身份标识”。

Session是 Web 应用程序中常用的会话跟踪机制。它是一种在服务器端存储用户状态信息的机制,通常用于存储用户的身份认证信息、会话标识符等敏感数据。它与 Cookie 不同,Session 会将用户的数据存储在服务端,并且会根据加密算法确保它的安全性。

 特点

  • Session 是基于 Cookie 实现,Cookie失效或删除则Session也无法获取。
  • Session 是存储在服务器端,所以安全性比Cookie高。
  • Session 可以存任意数据类型。
  • Session的默认生效时间是30分钟。只要在生效时间内,即使该Session值已被修改,依然可通过旧有Cookie访问到旧有Session值。
  • Session 可存储数据的容量远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。

Session和Cookie的对比

CookieSession
存放位置客户的浏览器服务器
安全性不安全安全
数据大小不能超过4K无数据类型和大小限制
生命周期预先设置的生存周期,或永久的保存于本地的文件IE启动到IE关闭

不足

  • 都基于浏览器 Cookie 实现,用户禁用 Cookie 后,系统就无法正常使用了。
  • 虽然Session具备一定的安全性,但是它的问题在于扩展性不好。比如涉及到服务器集群的场景,要求每台服务器都能够读取Session。这种场景一般解决方案是Session共享,经典应用需求是A和B两个关联网站间的单点登录,但是这种方案一般工程量较大
  • Session信息存到服务器,必然占用内存。用户多了以后,开销必然增大。为了提高效率,需要做分布式,做负载均衡。因为认证的信息保存在内存中,用户访问哪台服务器,下次还得访问相同这台服务器才能拿到授权信息,这就限制了负载均衡的能力。而且SeesionID存在Cookie,还是有暴露的风险,比如CSRF(Cross-Site Request Forgery,跨站请求伪造)

如何解决这些问题呢?基于Token令牌鉴权

Token

一种不需要自己存放 Session 信息就能实现身份验证的方式,通过这种方式服务器端就不需要保存 Session 数据了,只用在客户端保存服务端返回给客户的 Token 就可以了,扩展性得到提升。

特点

  • Token不需要再存储用户信息,节约了内存,token签发后存储在客户端,不占用服务器资源,可减轻服务器压力
  • 由于不存储信息,客户端访问不同的服务器也能进行鉴权,增强了扩展能力(解决跨域)
  • Token可以采用不同的加密方式进行签名,提高了安全性
  • 每一次请求都需要携带 token,需要把 token 放到 HTTP 的 Header 里

Token传递的过程跟Cookie类似,只是传递对象变成了Token。用户使用用户名、密码请求服务器后,服务器就生成Token,在响应中返给客户端,客户端再次请求时附带上Token,服务器就用这个Token进行认证鉴权。

Token虽然很好的解决了Session的问题,但仍然不够完美。服务器在认证Token的时候,仍然需要去数据库查询认证信息做校验。为了不查库,直接认证,JWT出现了。

JWT

JWT (JSON Web Token)通常可以称为 Json 令牌,本质上就是一段签名的 JSON 格式的数据。由于它是带有签名的,因此接收者便可以验证它的真实性。

JWT是RFC 7519 中定义的用于安全的将信息作为 Json 对象进行传输的一种形式。JWT 中存储的信息是经过数字签名的,因此可以被信任和理解。可以使用 HMAC 算法或使用 RSA/ECDSA 的公用/专用密钥对 JWT 进行签名。

作用

  • 认证(Authorization):这是使用 JWT 最常见的一种情况,一旦用户登录,后面每个请求都会包含 JWT,从而允许用户访问该令牌所允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销很小。
  • 信息交换(Information Exchange):JWT 是能够安全传输信息的一种方式。通过使用公钥/私钥对 JWT 进行签名认证。此外,由于签名是使用 head 和 payload 计算的,因此你还可以验证内容是否遭到篡改。

内容

  • Header :描述 JWT 的元数据。定义了生成签名的算法以及 Token 的类型。
  • Payload(负载):用来存放实际需要传递的数据(一般是Base64Url编码完成)
  • Signature(签名):服务器通过Payload、Header和一个密钥(secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

在服务器端需要存储以下信息:

  1. JWT的密钥:用于对JWT进行加密和解密,要保证密钥的安全性,不能外泄。

  2. 用户信息:JWT通常用来进行用户身份认证和授权,所以一般需要在服务端存储一些和用户相关的信息。通常,JWT中存储了用户的 id、用户名、角色等信息,服务器端需要将这些信息存储在用户的会话中,以便进行后续的鉴权验证。

  3. 过期时间:JWT需要设置过期时间,以保证安全性。因为JWT中的信息是经过加密的,无法修改,因此过期时间只能是JWT生成时设置,需要在服务器端存储JWT的生成时间和过期时间。

使用场景

JWT一般可暂时存储在localstorage或Cookie中方便获取:

  • 将JWT放在Cookie 里面自动发送,缺点是默认不可跨域。
  • 将JWT放在HTTP 请求头信息的 Authorization 字段里(主流做法)。
  • JWT就放在POST请求的数据体里。
  • JWT放在GET请求的参数里(即URL里)

JWT和Session的对比

JWTSession
存放位置客户的浏览器服务器
加密签名
可扩展性
跨域认证支持不支持

JWT的安全风险及防范措施

一、JWT的安全风险

  1. 签名篡改风险

    • 若使用弱加密算法(如HS256HS256配合弱密钥)或未正确验证签名算法,攻击者可篡改令牌内容并伪造签名。例如,将算法改为nonenone绕过验证。
    • 引用支持:JWT需依赖签名保证完整性,弱算法或密钥管理不当会导致令牌被篡改。
  2. 敏感信息泄露

    • JWT的头部(Header)和载荷(Payload)仅通过Base64Url编码,未加密。攻击者可解码后直接读取敏感数据(如用户ID、角色)。
  3. 令牌过期时间(Expiration)失效

    • 若未设置合理的expexp字段或令牌长期有效,攻击者可能通过窃取令牌实现持久化访问。
  4. 密钥管理漏洞

    • 硬编码密钥、密钥强度不足或未定期轮换,可能导致密钥泄露,进而引发大规模伪造攻击。
  5. 重放攻击

    • 攻击者截获有效令牌后,可重复使用该令牌访问系统资源。

二、防范措施

  1. 强制使用强签名算法

    • 优先选择非对称加密算法(如RS256RS256),避免使用HS256HS256或nonenone,并在服务端严格校验签名算法。
  2. 避免存储敏感信息

    • 载荷(Payload)中仅包含必要信息,敏感数据(如密码)应通过哈希处理后存储或完全避免传输。
  3. 合理设置令牌有效期

    • 为expexp字段赋予较短的有效期(如15分钟),并通过刷新令牌(Refresh Token)机制更新访问令牌。
  4. 强化密钥管理

    • 使用密钥管理系统(KMS)动态获取密钥,定期轮换密钥,并确保密钥复杂度符合安全标准2
  5. 防范重放攻击

    • 在令牌中添加唯一标识(如jtijti)或时间戳,服务端记录已使用的标识符,拒绝重复请求。
  6. 启用HTTPS传输

    • 全程使用HTTPS加密通信,防止令牌在传输过程中被截获。

三、扩展实践

  • 密钥轮换策略:定期更新公私钥对,旧密钥保留短暂时间以兼容未过期令牌。
  • 监控与日志:记录令牌使用情况,检测异常访问模式(如同一令牌频繁跨地域调用)。

解决跨域问题

单点登录需求:多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

这种需求需要解决跨域认证 以及 前端页面 JavaScript 跨域 问题,本文简单介绍跨域认证解决方式

Session持久化

如果采用传统的Session用户验证机制,则需要Session实现多系统共享。那么标准的实现方案就是​ 将 Session 数据持久化,写入数据库或别的持久层。各种服务受到请求后,都向持久层请求数据。

具体实现流程:

  1. 用户在A网站登录成功后,将 session 存储到 Redis 持久化存储,注意设置有效期。
  2. 此时访问 网站B 进行用户身份认证。注意 此时 访问 B的链接URL 要携带参数 sessionId!B 在处理请求- 身份验证时,先解析是否携带了sessionid参数,携带了则向 redis 中查询相关数据,并将数据保存到当前会话中。此时就成功登录 B 了。

JWT方案

用户在A网站登录成功后,服务器在客户生成加密的Token(如包含下面的信息),然后此时访问B系统同样携带此Token。服务端统一通过算法进行解密验证即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值