写在前面
- 翻阅了很多帖子后按自己的理解写了这篇博客,引用文章附在末尾,有引用到但未出现链接的文章请联系我,我一定立即进行修改更正。
- 也希望各位大佬不吝赐教。
01 | 白话理解Cookie、Session、Token
MTS是个日常生产蛋糕的公司,公司里有很多很多的员工,员工对于MTS来说都是相对独立的个体,且MTS的前台MM脸盲,即使员工的长相特征明显也判断不出来是自家的,不是自家的不给开门。那要如何判断自家员工呢?
MTS想了个办法,每当员工下班回家时,就让他们带上MTS工作证,上面印有MTS标志以及员工姓名及所属部门,这样第二天上班时就向前台MM出示工作证,前台MM知道是自己员工就开门。
这里的工作证对应的就是网络中的网址,假设公司网址为MTS.com, 你的所属部门是material材料部,那么网址就加上 “MTS.com?dep=material” , 你的名字叫做aL,网址就会变成“MTS.com?dep=material&name=aL” , 这样服务器就能根据网址上的信息来判断你是谁,属于哪个部门,即,你的状态是什么。
“工作证”确实对MM脸盲的情况有所帮助,但是在这个鲜少见到纸质材料的时代,带工作证实在是太麻烦了!!!! 那可怎么办呢?
MTS又想了个 办法,都2021年了,手机不离手的今天,我把信息记在你手机里总行了吧。于是,下班前,MTS在员工手机里留下了标志信息,上班时,前台MM只需要查看员工手机里是否有标志信息即可。这样不用带员工证方便了好多呢。
这里手机里的信息就是我们说的cookie,浏览器发送请求给服务器,服务器在浏览器中设置了cookie,然后将标志信息存放到cookie中(set-cookie),等下一次请求时,浏览器带着cookie给服务器发请求,服务器就能根据cookie中的数据内容判断出状态。
就这样,前台MM的脸盲症解决的差不多了。但因为MTS是个有志向、积极上进、有人情味的公司, 针对加班的员工进行记录以便发放加班津贴。
于是,MTS根据员工加班情况,在员工数据的标志信息上进行修改,如加班一天就写: 996=1,下个月结算工资时,就进行津贴结算。于是施行了一个月。一个月后老板发工资时,发现问题来了,明明员工只加班了19天,居然发出了26天的津贴??!!这还得了,估计是把 996=1改成了 996=7。
MTS化悲愤为力量,又想到了一个办法,既然员工手机上的信息被修改了,那把信息存储到公司电脑上不就好了,奈斯。就比如说,MTS在员工手机上留下员工号:[0001], 然后在公司电脑上留下信息:[0001, 996=1], 等明天上班时,我就能通过员工号查到真实的加班信息了。这时MTS突然想到,如果有人把员工号改成别人的那不就功亏一篑了吗,既然这样,那就不用员工号进行识别了,那我设置一串随机字符作为识别码吧,这样可是很难猜到其他人的标识码。于是员工手机上的信息:[an2msa926MDJA], 公司电脑上的信息:[an2msa926MDJA, 996=1 ] .
在网络中,使用cookie来记住用户状态,但是cookie里面的东西是可以被篡改的,这时就可以跟上面一样,将cookie中的信息进行加密。有两种方法,法一,cookie中存储全部信息,然后将全部信息进行加密(要加密的内容太多了)( Cookie-based session);法二,就是上面的方法,服务器在cookie中只存识别码( Session ID),然后对识别码进行加密,其他所有信息都在服务器端。
但是注意,一旦SessionID被偷走,别人就可以伪造你的身份来登陆。
session的工作流程可如下所示:
本质上来说,Cookie
是一段文本信息。Session
就是存储员工明细表,确认员工身份的地方。
Cookie机制是通过员工身上的员工证来确认身份,Session机制就是通过公司电脑上的员工明细表来确认员工身份。
看完了Session验证机制,我们再来看看另一种验证机制:Token。
老板昨天突发奇想,如果电脑宕机,数据库坏掉了,那MTS的员工数据怎么办,岂不是一夜之间所有自家人都不认识了? 于是老板又化食欲为动力,想了个办法。既然害怕公司数据存储丢失或者冗余的问题,那我干脆不存储了。当员工来上班时,老板给每个员工配了个令牌,使用特定的算法
+密钥
+原始数据
,生成一个签名
,再把数据+签名
绑在一起作为令牌,等明天员工上班时,员工只需要出示他的数据,前台MM根据密钥和算法算出签名,再与员工持有的签名进行比对,如果比对成功,那就是自家员工。但这也有一个问题,如果你的令牌被偷走了,那前台MM也没办法,就会认为小偷也是自家员工。
这里的令牌就是我们说的Token,服务器根据原始数据,选定算法如MD5,以及一个特定的密钥,对客户数据进行加密生成签名,再将签名与原始数据一起绑定作为Token,返回给客户端,由于密钥别人不知道,所以无法伪造Token。下次对同一网址发送request时,就将Token进行发送,服务器使用同样的方式对原始数据进行加密,如果签名相同则放行,否则就拒绝。注意:Token跟Session id一样,都会面临这被偷走的风险。这样一来,服务器不用保存session id, 只需要生成token,验证token,这也是一种时间换空间的策略。
Token验证流程如下图所示:
03 | 参考文献
- https://zhuanlan.zhihu.com/p/63061864
- https://www.jianshu.com/p/639ec8d53631
- https://cloud.tencent.com/developer/article/1457857
- https://hulitw.medium.com/session-and-cookie-15e47ed838bc
- https://github.com/aszx87410/blog/issues/45
- https://github.com/aszx87410/blog/issues/46
04 | 小tip
- md文档图片居中方法:在图片地址末尾加上 ,#pic_center 即可
- md文档段首缩进的问题:段首加上