现在基本上用的比较多的就是基于session,cookies和JWT会话管理机制,它们之间有什么优缺点和异同呢,简单总结一下。
一、为什么要使用会话管理
众所周知,http协议是一个无状态的协议,每个请求之间是独立的,没有关系的。但是在日常的实际应用中并不能满足我们的需求,比如一个购物网站,购物时,我们必须知道是哪个用户购买的商品,这时候我们就需要引入会话管理机制,区分不同的用户。
二、基于cookie和session的会话管理机制
2.1 session和cookie会话机制的原理
session是存放在服务端的,而cookie是存储在客户端的用户登录成功的时候,生成session_id,以session_id为key,用户信息经过一系列的加密处理生成value,写入session,session信息可以写入文件,数据库。也可以写入memcached等等,推荐写入memcached,提高访问的速度,然后把session_id写入cookie存放在客户端,每次请求的时候,都会携带cookie,需要用户信息的时候,根据cookies里面的session_id直接从文件或者数据库或者memcached里面取出session信息即可。
2.2 session和cookies的优缺点
- cooike的安全性不好,攻击者可以利用本地cookie进行欺骗和CSRF攻击
- 使用cookies,在多个域名的情况下会出现跨域的问题
- session存放在服务器端,短时间内如果有大量的用户,会影响服务器的性能,推荐使用menchched缓存
- 当有多台服务器的情况下,如何共享session也会是一个问题,也就是说,用户第一个访问的时候是服务器A,而第二个请求被转发给了服务器B,那服务器B如何得知其状态。
三、基于JWT的会话管理机制
3.1 JWT是什么
JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON对象安全传输信息。这些信息可以通过数字签名进行验证和信任。可以使用秘密(使用HMAC算法)或使用RSA的公钥/私钥对对JWT进行签名。
3.2 JWT如何工作
首先用户发出登录请求,服务端根据用户的登录请求进行匹配,如果匹配成功,将相关的信息放入payload中,利用上述算法,加上服务端的密钥生成token,这里需要注意的是secret_key很重要,如果这个泄露的话,客户端就可以随意篡改发送的额外信息,它是信息完整性的保证。生成token后服务端将其返回给客户端,客户端可以在下次请求时,将token一起交给服务端,一般来说我们可以将其放在Authorization首部中,这样也就可以避免跨域问题。接下来,服务端根据token进行信息解析,再根据用户信息作出相应的操作。
3.3 JWT的优缺点
3.3.1 JWT的优点
考虑JWT的实现,上面所述的关于session,cookies的缺点都不复存在了,不易被攻击者利用,安全性提高。利用Authorization首部传输token,无跨域问题。额外信息存储在客户端,服务端占用资源不多,也不存在session共享问题。感觉JWT优势很明显
3.3.2 JWT的缺点
登录状态信息续签问题。比如设置token的有效期为一个小时,那么一个小时后,如果用户仍然在这个web应用上,这个时候当然不能指望用户再登录一次。目前可用的解决办法是在每次用户发出请求都返回一个新的token,前端再用这个新的token来替代旧的,这样每一次请求都会刷新token的有效期。但是这样,需要频繁的生成token。另外一种方案是判断还有多久这个token会过期,在token快要过期时,返回一个新的token。
用户主动注销。JWT并不支持用户主动退出登录,当然,可以在客户端删除这个token,但在别处使用的token仍然可以正常访问。为了支持注销,我的解决方案是在注销时将该token加入黑名单。当用户发出请求后,如果该token在黑名单中,则阻止用户的后续操作,返回Invalid token错误。这个地方我再稍微补充一下,其实这里的黑名单操作也比较简单,把已经注销的token存入比如说一个set中,那么在每次进行token验证时,先检查在set中是否已经存在,如果已经存在的话,则视为token已经失效,直接返回未授权。这一部分在上面的授权代码中也可以看到,不过我是放到redis缓存中的。
四、总结
技术是为业务服务的,目前来说jwt还不能完全代替基于cookie的方式,我们可以使用token防止CSRF攻击,使用redis集群解决session的共享问题等等。