浅谈jwt与session
最近入门node,对比着之前的springboot在看对应的技术,之前用springboot做restful做会话保持的时候会用到session,后来偶然看到在node中很多接口调用使用的是无状态的jwt,于是对这两个用户认证技术产生了兴趣,下面是对于每个技术的介绍以及比较。
先给出结论,他们最根本的区别是,jwt的用户信息存在客户端,而session的用户信息存在服务端,这么说可能有点难理解,下面我来解释一下。
1.Session
对于session的业务逻辑来说,首先是用户发送用户名密码到服务器,然后服务器调取数据库判断用户是否拥有相关权利,然后将该用户信息存入服务端的内存(对于分布式来说是数据库以保持会话状态),等用户调用其他接口的时候,会从内存调用该用户的信息来决定是否提供接口服务。
那么服务端是怎么知道接口请求来自哪个客户端呢?这时候就需要利用到浏览器上的Cookies机制了,当我用户请求登录的时候,服务器会生成sessionId,这是对于用户信息储存的键值对的“键”,与此同时将这个id通过用户登录接口返回的数据设置set-cookies将sessionId放到浏览器的cookies中,当用户调用其他接口的时候会携带该cookies,服务端就会将cookies中的sessionId取出并在session池中寻找该用户信息并且赋予相关权利,特别注意的是,当服务器重启后,session存在内存中的单台服务器会失去所有的会话连接。
2.JWT
如果说对于session来说是实名制验证身份入场的话,jwt可以看做是使用门票入场,当用户调用登录接口之后,服务器会将用户信息加密之后,将所有信息发送到客户端的cookies中,由客户端保存,当需要使用的时候,客户端需要将自己的门票出示,来获得相关的服务,服务端只负责签发门票和验证门票的真假,不保存门票的信息。服务器重启之后,所有信息还会保存,但是由于服务器中没有保存相关信息,如果要更新用户信息的话,必须使得当前的秘钥失效,通常会导致用户信息更新不及时的问题。
3.比较
对于保持会话来说,我个人是比较推荐传统的session机制的,因为jwt是无状态的,用户信息更新不及时可能会导致安全问题而致使jwt的验证是一次性的,除此之外,将用户信息通过加密的方式存放在客户端是存在可能被破解解密的情况的,而且就基于性能上来说,session是将压力集中到服务端,当用户量达到一定程度的时候会对服务器的性能造成一定的影响,但是对于jwt来说,将用户信息全部放到cookies中会导致网络数据传输量大大增加,同样会导致更大的性能隐患,所以,在单点登录和会话保持我是不推荐的。
当然,jwt就没用用武之地了吗,当然不是,基于其无状态的特点,该技术很适合restful api的授权验证,信息不常变动,不需要服务器长期记录状态,减少服务器的压力。