Cookie、Session、Token、JWT区别和关系
Cookie
- 浏览器登录时,会将用户名和密码发送给服务器。服务器验证用户名和密码判断是哪个用户的请求
- 但是之后的请求需要一直带上用户名和密码,缺少安全性
- Cookie由此而生,Cookie是服务器验证完用户名和密码后返回给客户端的用户凭证,一般是用户ID和用户名的组合
- 但是用户ID+用户名很容易给不怀好意的人猜到,从而获取到用户权限。
- 所以一般会在cookie中放置数据签名(例如,把cookie中所有的数据连起来,拼接上存在服务器中的密令,取Hash值作为签名)
- 签名随同数据一并发给浏览器作为Cookie,用户不知道服务器密令,所以无法伪造cookie
Session
- 如果不想浏览器cookie保存太多信息,则可以将用户信息保存在服务器中,并生成一个足够长的key作为session_id传回浏览器作为cookie
- 后续cookie传回可以通过session_id判断用户,查找出用户数据
- 这个过程就是Session,session本质上还是一种cookie,不同点在于只传回session_id作为唯一标识,会话数据全都保存在服务器中,由服务器自行管理
Token
- 移动互联网中,除了网页还有APP和小程序,这种客户端接口默认没有Cookie机制的
- 将服务器保存的key传输回客户端,但是不再命名为session_id,而是直接作为Token,代替Cookie+serssion_id的组合
- session和token本质是一样,只是少了浏览器的cookie机制,需要自己维护
- 而因为缺少了cookie机制,所以客户端请求的时候不再使用cookie字段,而是转用Authorization字段代替
以上是单一服务器的情况,在分布式服务器中,容易导致一个服务器没有会话而导致鉴权失败
分布式服务器
- 通常解决上述问题,需要在服务端再架设一个中心化的存储服务,例如,Redis专门存储会话数据
- 但是中心化的方式容易造成服务端的性能瓶颈,Redis中心化的崩溃会导致所有服务器连带崩溃
- 项目中更多的是希望用户鉴权数据保存在客户端,接口尽可能是无状态的。
- 所以可以将Cookie的数据作为Token保存在客户端中,这样服务器不需要保存用户的鉴权数据。可以更大的提升服务器的性能。
- 但是Cookie的加密方式是我们自己想,很可能存在漏洞。每个人的算法也不一样,这样不方便协作
JWT
- JWT是Token生成的一个标准
- 这样生成的Token由三部分组成
- 第一部分,头部包含Hash算法和Token类型
- 第二部分,载体携带会话数据
- 第三部分,是签名,原理与我们生成的Cookie签名相类似
- 但是虽然JWT生成的Token像是加密的,其实谁都可以解开。所以敏感信息,像是密码之类的不要保存在Token中