JWT(Json Web Token)和Session在网站开发中都有各自的用途,选择哪种方法取决于你的具体需求和应用场景。
JWT(Json Web Token)是一种轻量级的身份验证机制,它将用户的身份信息加密成一个JWT令牌,通过HTTP头部发送给服务器。JWT的优点包括:
1. 跨域:JWT可以在不同域之间传递,不需要Cookie,安全性更高。
2. 无状态:JWT不需要服务器保存状态信息,减轻服务器压力。
3. 体积小:JWT是JSON格式,适合前后端分离的架构。
然而,JWT也有缺点,如用户信息过长,存储和加密算法的管理需要考虑。
Session(会话)是一种传统的身份验证方式,通常通过Cookie在客户端存储一个会话ID,服务器通过这个ID来识别用户。Session的优点包括:
1. 简单:实现相对简单,适用于小型项目或对性能要求不高的场景。
2. 易于理解:开发者更熟悉Session的使用。
Session的缺点包括:
1. 跨域问题:Cookie受到同源策略限制,不能在不同域名之间传递。
2. 保存在客户端:可能会面临安全问题,如Cookie被盗取。
3. 依赖服务器状态:需要服务器保存用户的会话信息,如果服务器挂掉,可能会导致会话丢失。
综上,对于小项目,如果对安全性要求不高,且性能不是关键问题,Session可能是更合适的选择。如果项目涉及跨域或者追求更高效、安全性更高的设计,JWT可能是更好的选择。
基本信息容易变动。如果是一般的后台管理系统,肯定会涉及到人员的变化,那么其权限也会相应变化,如果使用JWT,那就需要服务器端进行主动失效,这样就将原本无状态的JWT变成有状态,改变了其本意。
无状态JWT一旦被生成,就不会再和服务端有任何瓜葛。一旦服务端中的相关数据更新,无状态JWT中存储的数据由于得不到更新,就变成了过期的数据。
session的跨平台可能就不那么好做了小项目工长职责怎么写简历,需要考虑的地方在于用户信息存储的格式,ProtoBuf、json、xml等,管理的话可能就需要专门的统一登录平台,这个就不展开了。
小项目总jwt好还是session好
JWT理论上用于无状态的请求,因此其用户管理也只是依赖本身而已。我们一般是在它的payload中加入过期时间,在不增加额外管理的情况下,它只有自动过期的方式。
JWT的header和payload其实是有json转变过来的,而signature其实就是一个加密后的字符串,因此解析起来较为简单,不需要其他辅助的内容。
为什么我们要把JWT和Session做对比呢?因为我们主要在每一次请求的认证时会用JWT,在此之前我们都是用Session的。那这两者的区别在哪儿呢?
signature则是将header和payload对应的json结构进行base64url编码之后得到的两个串用英文句点号拼接起来,然后根据header里面alg指定的签名算法生成出来的。
它由三部分组成:header(头部)、payload(载荷)、signature(签名),以.进行分割。(这个字符串本来是只有一行的,此处分成3行,只是为了区分其结构)
自包含:这个串可以包含很多信息,比如用户的id、角色等,别人拿到这个串,就能拿到这些关键的业务信息,从而避免再通过数据库查询等方式才能得到它们。
使用JWT来传输数据,实际上传输的是一个字符串,这个字符串就是所谓的json web token字符串。所以广义上,JWT是一个标准的名称;狭义上,JWT指的就是用来传递的那个token字符串。这个串有两个特点:
JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑和自包含的方式,用于在各方之间作为JSON对象安全地传输信息。作为标准,它没有提供技术实现,但是大部分的语言平台都有按照它规定的内容提供了自己的技术实现,所以实际在用的时候,只要根据自己当前项目的技术平台,到官网上选用合适的实现库即可。
如今,越来越多的项目开始采用JWT作为认证授权机制,那么它和之前的Session究竟有什么区别呢?今天就让我们来了解一下。
另外,不用 JWT 直接使用普通的 Token(随机生成的 ID,不包含具体的信息) 结合 Redis 来做身份认证也是可以的。
JWT 也不是银弹,也有很多缺陷,具体是选择 JWT 还是 Session 方案还是要看项目的具体需求。万万不可尬吹 JWT,而看不起其他身份认证方案。
JWT 其中一个很重要的优势是无状态,但实际上,我们想要在实际项目中合理使用 JWT 的话,也还是需要保存 JWT 信息。
在某些情况下,使用传统的 Token 可能更合适。传统的 Token 通常只是一个唯一标识符,对应的信息(例如用户 ID、Token 过期时间、权限信息)存储在服务端,通常会通过 Redis 保存。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
JWT 结构复杂(Header、Payload 和 Signature),包含了更多额外的信息,还需要进行 Base64Url 编码,这会使得 JWT 体积较大,增加了网络传输的开销。
存在安全问题,只要拿到了未过期的 refreshJWT 就一直可以获取到 accessJWT。不过,由于 refreshJWT 只用来获取 accessJWT,不容易被泄露。
重新请求获取 JWT 的过程中会有短暂 JWT 不可用的情况(可以通过在客户端设置定时器,当 accessJWT 快过期的时候,提前去通过 refreshJWT 获取新的 accessJWT);
客户端登录后,将 accessJWT 和 refreshJWT 保存在本地,每次访问将 accessJWT 传给服务端。服务端校验 accessJWT 的有效性,如果过期的话,就将 refreshJWT 传给服务端。如果有效,服务端就生成新的 accessJWT 给客户端。否则,客户端就重新登录即可。
第一个是 accessJWT ,它的过期时间 JWT 本身的过期时间比如半个小时,另外一个是 refreshJWT 它的过期时间更长一点比如为 1 天。refreshJWT 只用来获取 accessJWT,不容易被泄露。
这种方案满足于大部分场景。假设服务端给的 JWT 有效期设置为 30 分钟,服务端每次进行校验时,如果发现 JWT 的有效期马上快过期了,服务端就重新生成 JWT 给客户端。客户端每次请求都检查新旧 JWT,如果不一致,则更新本地的 JWT。这种做法的问题是仅仅在快过期的时候请求才会更新 JWT ,对客户端不是很友好。
我们先来看看在 Session 认证中一般的做法: 假如 Session 的有效期 30 分钟,如果 30 分钟内用户有访问,就把 Session 有效期延长 30 分钟。
另外,对于修改密码后 JWT 还有效问题的解决还是比较容易的。说一种我觉得比较好的方式: 使用用户的密码的哈希值对 JWT 进行签名。因此,如果密码更改,则任何先前的令牌将自动无法验证。
如果用户同时在两个浏览器打开系统,或者在手机端也打开了系统,如果它从一个地方将账号退出,那么其他地方都要重新进行登录,这是不可取的。
如果服务是分布式的,则每次发出新的 JWT 时都必须在多台机器同步密钥。为此,你需要将密钥存储在数据库或其他外部服务中,这样和 Session 认证就没太大区别了。
我们为每个用户都创建一个专属密钥,如果我们想让某个 JWT 失效,我们直接修改对应用户的密钥即可。但是,这样相比于前两种引入内存数据库带来了危害更大:
和上面的方式类似,使用内存数据库比如 Redis 维护一个黑名单,如果想让某个 JWT 失效的话就直接将这个 JWT 加入到 黑名单 即可。然后,每次使用 JWT 进行请求的话都会先判断这个 JWT 是否存在于黑名单中。
将有效的 JWT 存入数据库中,更建议使用内存数据库比如 Redis。如果需要让某个 JWT 失效就直接从 Redis 中删除这个 JWT 即可。但是,这样会导致每次使用 JWT 都要先从 Redis 中查询 JWT 是否存在的步骤,而且违背了 JWT 的无状态原则。
这个问题不存在于 Session 认证方式中,因为在 Session 认证方式中,遇到这种情况的话服务端删除对应的 Session 记录即可。但是,使用 JWT 认证的方式就不好解决了。我们也说过了,JWT 一旦派发出去,如果后端不增加其他逻辑的话,它在失效之前都是有效的。
使用 Session 进行身份认证的话,实现单点登录,需要我们把用户的 Session 信息保存在一台电脑上,并且还会遇到常见的 Cookie 跨域的问题。但是,使用 JWT 进行认证的话, JWT 被保存在客户端,不会存在这些问题。
安全性: 移动设备通常处于不受信任的网络环境,存在数据泄露和攻击的风险。将敏感的会话信息存储在移动设备上增加了被攻击的潜在风险。
兼容性: 移动端应用通常会面向多个平台,如 iOS、Android 和 Web。每个平台对于 Session 的管理和存储方式可能不同,可能导致跨平台兼容性的问题;
状态管理: Session 基于服务器端的状态管理,而移动端应用通常是无状态的。移动设备的连接可能不稳定或中断,因此难以维护长期的会话状态。如果使用 Session 进行身份认证,移动应用需要频繁地与服务器进行会话维护,增加了网络开销和复杂性;
但是,使用 JWT 进行身份认证就不会存在这种问题,因为只要 JWT 可以被客户端存储就能够使用,而且 JWT 还可以跨语言使用。
使用 Session 进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到 Cookie(需要 Cookie 保存 SessionId ),所以不适合移动端。
new XSSRequestWrapper((HttpServletRequest) request);
FilterChain chain) throws IOException, ServletException {
public void doFilter(ServletRequest request, ServletResponse response,
CSRF(Cross Site Request Forgery) 一般被翻译为 跨站请求伪造 ,属于网络攻击领域范围。相比于 SQL 脚本注入、XSS 等安全攻击方式,CSRF 的知名度并没有它们高。但是,它的确是我们开发系统时必须要考虑的安全隐患。就连业内技术标杆 Google 的产品 Gmail 也曾在 2007 年的时候爆出过 CSRF 漏洞,这给 Gmail 的用户造成了很大的损失。
就比如说,我们想要在 JWT 有效期内废弃一个 JWT 或者更改它的权限的话,并不会立即生效,通常需要等到有效期过后才可以。再比如说,当用户 Logout 的话,JWT 也还有效。除非,我们在后端增加额外的处理逻辑比如将失效的 JWT 存储起来,后端先验证 JWT 是否有效再进行处理。具体的解决办法,我们会在后面的内容中详细介绍到,这里只是简单提一下。
JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。
JWT 不是银弹,也有很多缺陷,很多时候并不是最优的选择。这篇文章,我们一起探讨一下 JWT 身份认证的优缺点以及常见问题的解决办法,来看看为什么很多人不再推荐使用 JWT 了。理性探讨,欢迎在评论区说说你的看法。
校招面试中,遇到大部分的候选者认证登录这块用的都是 JWT。提问 JWT 的概念性问题以及使用 JWT 的原因,基本都能回答一些,但当问到 JWT 存在的一些问题和解决方案时,只有一小部分候选者回答的还可以。
但这种场景也不是没有办法解决,解决办法就是将JWT生成的token存入到redis或者数据库中,当用户登出或作出其他想要让token失效的举动,可通过删除token在数据库或者redis里面的对应关系来解决这个问题。
例如有个这种场景,如果JWT中存储有权限相关信息,比如当前角色为 admin,但是由于JWT所有者滥用自身权利,高级管理员将权利滥用者的角色降为 user。但是由于 JWT 无法实时刷新,必需要等到 JWT 过期,强制重新登录时,高级管理员的设置才能生效。
现代web应用程序的另一种常见模式是做小项目投资的创投公司,它们通常依赖于下游服务。例如,在原始请求被解析之前,对主应用服务器的调用可能会向下游服务器发出请求。这里的问题是,cookie不能很方便地流到下游服务器,也不能告诉这些服务器关于用户的身份验证状态。由于每个服务器都有自己的cookie方案,所以阻力很大,并且连接它们也是困难的。JSON Web Token再次轻而易举地做到了!
值得一提的是,token可能需要访问后端的数据库。特别是刷新token的情况。他们可能需要访问授权服务器上的数据库以进行黑名单处理。获取有关刷新token和何时使用它们的更多信息。
JWT通过将数据保留在客户端的方式以空间换时间。你应用程序的数据模型是一个重要的影响因素,因为通过防止对服务器数据库不间断的调用和查询来减少延迟。需要注意的是不要在JWT中存储太多的claim,以避免发生巨大的,过度膨胀的请求。
编码时,JWT的大小将是SESSION ID(标识符)的几倍,从而在每个HTTP请求中,JWT比SESSION ID增加更多的开销。而对于session,每个请求在服务器上需要查找和反序列化session。
对此的批判性分析是非常必要的。当从客户端向服务器发出请求时,如果大量数据在JWT内进行编码,则每个HTTP请求都会产生大量的开销。然而,在会话中,只有少量的开销,因为SESSION ID实际上非常小。看下面这个例子:
另一个挑战是,由一个服务器提供API,而实际应用程序从另一个服务器调用它的模式是很常见的。为了实现这一点,我们需要启用跨域资源共享(CORS)。Cookie只能用于其发起的域,相对于应用程序,对不同域的API来说,帮助不大。在这种情况下使用JWT进行身份验证可以确保RESTful API是无状态的,你也不用担心API或应用程序由谁提供服务。
RESTful API的原则之一是它应该是无状态的,这意味着当发出请求时,总会返回带有参数的响应,不会产生附加影响。用户的认证状态引入这种附加影响,这破坏了这一原则。保持API无状态,不产生附加影响,意味着维护和调试变得更加容易。
现代应用程序的常见模式是从RESTful API查询使用JSON数据。目前大多数应用程序都有RESTful API供其他开发人员或应用程序使用。由API提供的数据具有几个明显的优点,其中之一就是这些数据可以被多个应用程序使用。在这种情况下,传统的使用session和Cookie的方法在用户认证方面效果不佳,因为它们将状态引入到应用程序中。
专题:
新农村创业
农村创业妹
搜农村创业