首页 > 其他分享 >【杂谈】如何选择:Session 还是 JWT?

【杂谈】如何选择:Session 还是 JWT?

时间:2024-12-16 12:58:19浏览次数:5  
标签:存储 凭证 JWT 杂谈 Session 服务端 客户端

服务端如何验证客户端已经登录?

在用户成功登录后,服务端会发放一个凭证。之后,客户端的每次请求都需要携带该凭证,服务端通过验证凭证的有效性来判断用户是否已登录,并处理请求。

以下是 SessionJWT 在这方面的不同之处:

1. 凭证的内容是什么?

  • Session:凭证是一个简单的 ID 字符串,用于映射服务端存储的会话信息。
JSESSIONID=8C3C44A3A0B522F1B93D3F8C4F17F2E7; Path=/your-web-app; HttpOnly
  • JWT:凭证是一个 自包含 的令牌,解码后可以直接获得会话信息(如用户信息、权限等)。
//JWT token格式
<Header>.<Payload>.<Signature>

//JWT 案例Token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.S5rf1jOSGbHkGBv1buVpzCHYtoJXnJkK9J9M2yExhms

//JWT 案例token 各部分解码
{"alg":"HS256","typ":"JWT"}.{"userId":"1234567890","name":"John Doe","iat":1516239022}.S5rf1jOSGbHkGBv1buVpzCHYtoJXnJkK9J9M2yExhms

//注意:JWT并不是加密数据,只是提供了签名防止内容被篡改。Header和Payload都是明文。

2. 凭证如何传输?

  • Session:服务端通过 Set-Cookie 方式将凭证发送给客户端,客户端将凭证存储在 cookie 中,并在每次请求中通过 Cookie 头部将其发送回服务端。
  • JWT:服务端将凭证返回给客户端,客户端存储在 localStoragesessionStorage 中。后续请求中,客户端通过 Authorization 头部将 JWT 传递给服务端。

3. 服务端如何检测凭证?

  • Session:服务端根据接收到的 sessionId 查询会话信息,若会话存在则验证通过,服务端继续处理请求。
  • JWT:服务端验证 JWT 中的签名,签名通过表明凭证未被篡改,且确实是由服务端签发的。(二开应用记得修改JWT签名密钥,否则其他系统的JWT也能访问你的系统)

4. 认证信息存储在哪里?

  • Session:认证信息存储在服务端内存中,或存储在共享的内存系统(如 Redis)中。
  • JWT:认证信息存储在客户端的凭证中,JWT 令牌本身包含了所有认证信息。

关于水平扩展

Session 的缺点

当系统只有单个服务时,会话信息可以存储在应用内部。但一旦服务拆分为多个节点,会话信息需要迁移到共享存储(如 Redis)。此时,所有服务的请求都必须访问 Redis。如果 Redis 故障或宕机,服务将无法正常工作,直到 Redis 恢复。

JWT 的优势

JWT 的一个主要优势是其 自包含 特性,所有认证信息都存储在客户端的凭证中。由于 JWT 的签名是通过服务端的密钥进行验证,服务端无需访问共享存储系统(如 Redis),每个服务节点都可以独立地验证凭证。这使得 JWT 在分布式架构中更具优势,避免了 Redis 故障时的单点风险。


关于会话控制

Session 的优点

由于会话信息存储在服务端,服务端可以方便地管理会话。例如,若需要 踢人,可以直接删除 Redis 或内存中的会话信息,之后客户端的请求会被拒绝,用户需重新登录。

JWT 的缺点

由于 JWT 在客户端存储,服务端无法直接删除客户端的凭证。如果需要实现踢人操作,服务端必须记录用户签发的 token ID,并通过 黑名单 来阻止客户端使用已失效的凭证。

有时候有人担心使用黑名单会与 Session 的方式相似,仍然依赖于一个中心数据存储。但可以通过以下方式解决:

  • 中心数据(Redis)存储用户签发的情况,并将黑名单推送到各个应用。
  • 每个应用本地保存黑名单副本,这样就不需要频繁查询中心存储。

此外,JWT 有过期时间,黑名单可以设置相同的过期时间,避免过多的数据存储。并且,踢人操作并不频繁,所以黑名单的数据量不会很大。

如果不需要“立即”封禁 JWT,可以考虑使用 短生命周期的 JWT 结合 刷新机制。这种方式也非常常见。即服务端返回两个 token:

  • access_token (JWT)
  • refresh_token (通常是一个 UUID,服务端保存该 key 到 Redis 中,value 为用户信息)

客户端使用 refresh_token 生成新的 access_token

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.S5rf1jOSGbHkGBv1buVpzCHYtoJXnJkK9J9M2yExhms
"
    "refresh_token": "c0cdf579-54d5-46fc-8e1b-bd42bd01b556"
}

 


关于会话存储的内容

  • Session:由于会话信息存储在服务端,服务端可以在会话中存储一些经常访问的数据。
  • JWT:JWT 的会话内容是 明文 的,虽然签名可以防止篡改,但依然可能被读取,因此敏感数据不应放在 JWT 中。另外,JWT 是每次请求都携带的,数据过大会占用带宽,因此不适合存储过多的信息。

关于页面路由控制

  • JWT 非常适合 SPA(单页面应用),因为页面路由控制通常由前端负责,后端仅通过 JWT 验证数据访问权限。

  • 对于 MPA(多页面应用),使用 JWT 控制页面访问时会遇到困难。因为在浏览器行为(如页面刷新)中,JWT 需要通过 Authorization 头部传递,但刷新页面时,浏览器行为不能直接携带该信息。

解决方案:后端可以在用户登录时不仅在 body 中返回 JWT,还通过 Set-Cookie 传递 token。这样客户端请求时会自动携带 JWT,后端校验的时候可以从 CookieAuthorization 头部两个数据源获取 token。


总结

  • Session:将会话信息存储在服务端,凭证是会话 ID,适用于单一应用场景或需要共享内存(如 Redis)的环境,但依赖于共享存储系统。
  • JWT:凭证包含所有认证信息,并通过签名确保其完整性,适用于分布式架构,且无需依赖外部存储系统。

在拆分为多个服务的分布式系统中,JWT 通过自证机制避免了单点故障的风险,而 Session 则需要一个可靠的存储系统来共享会话信息。具体选择哪种方式,应根据系统的规模、需求和容错能力来决定。

标签:存储,凭证,JWT,杂谈,Session,服务端,客户端
From: https://www.cnblogs.com/longfurcat/p/18609842

相关文章

  • 爬虫基础之Session和Cookie
    在浏览网站的过程中,我们经常会遇到需要登录的情况,有些页面只有登录之后才可以访问。在登录之后可以连续访问很多次网站,但是有时候过一段时间就需要重新登录。还有一些网站,在打开浏览器时就自动登录了,而且在很长时间内都不会失效,这又是什么情况?其实这里面涉及Session和C......
  • 【杂谈】后台日志该怎么打印
    为什么要打印日志?1.监控系统运行情况定期查看系统日志是了解服务是否正常运行的重要手段。日志为运维人员提供了实时监控系统状态、发现潜在问题的关键信息。2.排查问题(例如异常栈)日志记录了详细的错误信息,特别是异常栈,有助于快速定位问题的根源。对于一些偶发的Bug,日志是......
  • iOS app 自动化测试,appium inspector 启动会话报错:Failed to create session. An unkn
    报错内容:Failedtocreatesession.Anunknownserver-sideerroroccurredwhileprocessingthecommand.Originalerror:'12.5.5'doesnotexistinthelistofsimctlSDKs.OnlythefollowingSimulatorSDKversionsareavailableonyoursystem:15.2,......
  • 网络通信与状态管理:深入理解Cookie、Session及Web工具
    前言:在当今数字化的网络世界中,Web技术的基石构建起了我们丰富多彩的互联网体验。其中,Cookie和Session犹如隐匿于幕后的关键使者,默默地在客户端与服务器之间传递着信息,管理着用户的状态与交互数据,深刻影响着我们在各类网站与应用中的每一次操作与交互流程。与此同时,Link......
  • SqlSessionTemplate
    SqlSessionTemplate是MyBatis提供的一个非常重要的类,通常在Spring与MyBatis集成时使用。它用于简化MyBatis的SqlSession操作,并提供了线程安全的封装,以便在Spring的环境中高效地执行数据库操作。基本概念SqlSession:SqlSession是MyBatis提供的核心接口,用于执......
  • Spring Security6 实现数据库自定义验证和jwt校验
    SpringSecurity6数据库自定义验证和jwt校验的简单实现以及个人解读版本springboot3.4.0mybatis-plus3.5.7jjwt0.12.6在使用jjwt的时候需要导入三个依赖分别是jjwt-api,jjwt-impl和jjwt-jackson,导入三个有点麻烦,所以可以直接导入jjwt依赖,这个依赖包含前面三个<depen......
  • 网络通信与状态管理:深入理解Cookie、Session及Web工具
    前言:在当今数字化的网络世界中,Web技术的基石构建起了我们丰富多彩的互联网体验。其中,Cookie和Session犹如隐匿于幕后的关键使者,默默地在客户端与服务器之间传递着信息,管理着用户的状态与交互数据,深刻影响着我们在各类网站与应用中的每一次操作与交互流程。与此同时,Links、Wge......
  • Cookie、Session、Filter过滤器
    一、Cookie####1.1工作原理客户端请求服务器后,如果服务器需要记录用户状态,服务器会在响应信息中包含一个Set-Cookie的响应头,客户端会根据这个响应头存储Cookie信息。再次请求服务器时,客户端会在请求信息中包含一个Cookie请求头,而服务器会根据这个请求头进行用户身份、状态......
  • JWT 令牌:原理、应用与安全考量
    深入理解JWT令牌:原理、应用与安全考量文章目录深入理解JWT令牌:原理、应用与安全考量一、引言二、JWT令牌与传统方式的区别(一)传统身份验证方式的特点与局限(二)JWT令牌的优势三、JWT令牌的字段(一)头部(Header)(二)载荷(Payload)(三)签名(Signature)四、JWT令牌在集群部署中......
  • 【Spring Boot编程】request session, global session 这几种作用域没有见过
    在Spring框架中,Bean的作用域(Scope)决定了Bean的生命周期和可见性。常见的作用域包括singleton、prototype、request、session和application。你提到的request、session和globalsession作用域主要用于Web应用程序。下面详细介绍这些作用域及其用途,帮助你更好地理解和应用它们。一......