畅购09:了解一下关于session和token以及常用的解决方案

三世轮回 提交于 2020-01-30 12:51:38

有关商品那部分实在是太无聊,照着视频做完全没有任何问题,所以我就不记录了。在后面有关微服务网关、JWT和OAuth2.0的学习过程中可以说是很一头雾水。

我花了大概两天时间把畅购这一块捋清楚后,基于畅购设计一套自己的微服务,在学习畅购的时候,由于JWT令牌自身特性导致令牌一旦发放则无法撤销,也就是说,我们没办法像之前那样将用户强制下线,即使用户点击注销,该令牌也会持续生效直到过期。
在这里插入图片描述

所以我在设计这套微服务的时候,将用户信息存到了Redis中,以token为key,实现了记录用户状态的功能,但是在后来学习相关资料的时候,发现这样其实破坏了JWT无状态的原则,如果要保证用户状态的话,还不如使用session管理用户。那么怎样才能比较友好的选择一个合适的方法保证API的安全性呢?

在这之前,我们先了解一下session和token。

1、什么是session和token

相信各位在学习JavaWeb的时候一定做过用户登录和注销的功能,我们知道,HTTP是无状态协议,它没办法告诉你这个请求是张三发给你的,为了解决这个问题,session和cookie就出现了。

session原理

浏览器第一次访问服务器,服务器会创建一个session,然后同时为该session生成一个唯一的会话的key,也就是sessionid,然后,将sessionid及对应的session分别作为key和value保存到缓存中,也可以持久化到数据库中。

然后服务器再把sessionid,以cookie的形式发送给客户端。这样浏览器下次再访问时,会直接带着cookie中的sessionid。然后服务器根据sessionid找到对应的session进行匹配。(PS:所以当面试官问你cookie被禁用时session还会生效吗你应该知道怎么回答了吧)

互联网发展带来的问题

有了session,用户的登录状态能记录了,讲道理到这里应该已经完美收官,可为什么还会出现token呢?这时候我们不得不谈谈web的发展了。

session解决了无状态的问题,但是新的问题随之而来:成千上万的session会给服务器带来极大的压力,同时分布式架构的出现,session之间没办法在服务器之间共享,这对于集群来说简直是噩梦。如果把session全部集中在一个服务器管理,一旦该服务器宕机,整个网站都会瘫痪。

之前得心应手的session无法满足需求,那么该怎么解决问题呢?我们回过头来思考一下,识别你是不是张三,session的原理在于根据sessionid匹配。

就像一个门禁系统,session相当于你和我都保存了一把一模一样的钥匙,只有比对成功才能识别你的身份。一百万个用户我的服务器就会有一百万把钥匙,这显然是不符合情理的。那么能不能,这把钥匙只交给你保存,我只负责验证呢?

优雅而不完美的token

我们再来换一种验证思路,如果说之前是你拿着门禁卡过来验证,我仍然需要去我的系统里面查一遍你这门禁卡是否有效,那么现在的思路就是,不管你是谁,只要你拿着张三的门禁卡开了门,你就是张三。

就相当于用户在登录的时候我给你一张门禁卡,上面写着“张三”两个大字,你每次进来只要给我看看这张门禁卡就好了。但是这样岂不是李四也可以伪造一张张三的门禁卡为所欲为了?

于是我们还需要在门禁卡上面做点手脚,用加密算法对名字加密!

于是原本写着“张三”两个汉字的门禁卡上面,就变成了“lZauD9Gc8PHSpHgdIeUB0A==”。你李四再NB,也没办法组合出和我一模一样的字符串,自然也就没办法为所欲为了。

看到这里,我们已经解决了刚才的问题,讲道理应该完美收官了,可为什么要说不完美的token呢?

token的优缺点

token的优点显而易见,轻量级,无状态、可扩展,但是缺点也很明显。

首先,我们没办法控制用户的登录状态。
因为token的签发是无法撤销的,只要用户手里的令牌还没有过期,就算你不想他登录,他依然能使用这枚令牌进入你的系统。

举个栗子:张三的门禁卡是管理员级别,整个公司四通八达想干嘛干嘛。突然有一天被降级变成了锅炉房保安,除了锅炉房和厕所哪儿都去不了。张三不乐意,于是找到了之前的管理员门禁卡一刷,系统又响起了:“尊敬的管理员张三您好”。

不仅如此,就算哪天张三家里的二哈叼着这张门禁卡过来一刷,系统依然会放行,这就意味着,拥有token的不管是人还是狗,只要合法,你就是张三。

解决方案

首先要明确一点的是,session和token这两者解决方案都有它们自己的优点和缺点,在实际生产中我们应该根据业务需求来决定使用哪种方案。就像eureka和zookeeper,没有最好的,只有最合适的。

想要解决token上述的问题也并非没有办法,这里贴一张大神的解决方案:
在这里插入图片描述

至于安全问题,我们只需要保证自己的请求是基于HTTPS就不用担心token会在传输过程中被窃取,下一章,我们将讨论OAuth2.0和JWT之间的联系
(PS:博主只是一枚大四的小白,所以上述论述仅代表个人观点,如有不对欢迎讨论指正)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!