三十年前,我找了一份好工作,生活很悠闲。
没错,我就是个HTTP服务器,我的创造者们对我很好, 他们制定的HTTP协议超级简单, 就是请求<--->响应。
我特别喜欢HTTP协议的无状态:
无状态是由业务决定的,30年前的Web 基本上就是文档的浏览而已, 既然是浏览,我作为一个服务器, 为什么要记住谁在一段时间里都浏览了什么文档呢?
可是好日子没持续多久,交互式的Web迅速兴起,论坛、购物、聊天等网站都要求我记住一个人的登录状态。
我没有办法,只好给每个登录的人造一个箱子,把每个应用想放的东西放进去
这个叫session的办法能区分开登录的用户,大家都很高兴。
可是,每个浏览器只需要保存自己的session id,而我需要保存所有人的session id ! 如果访问我的人多了, 就得有成千上万,甚至几十万个。
有些不着调的家伙还疯狂地往箱子里塞东西!
居然把庞大的购物车都放到session中。
这对我来说是一个巨大的开销 ,我不得不建了一座新房子
很快,麻烦来了
这样的事情越来越多,没办法,我只好做session的复制
后来,我遇到了一个叫做Redis的家伙,让我集中存储到他那里。
Redis的新方案虽然不错,但是增加了单点失败的可能性, 要是那个Redis的机器挂了, 所有人都得重新登录一遍, 估计得被人骂死。
我也尝试把这个单点的机器也搞出集群,增加可靠性, 但不管如何, 这小小的session 对我来说是一个沉重的负担。
但是让客户端去保留状态信息,有很大的安全漏洞,那些不怀好意的人可能伪造箱子。
关键点是验证,我得给这个箱子增加一点信息,证明是我创建的。
该怎么实现呢?Https这家伙给我支了一个招:
然后在把这个签名和之前的数据放到一起,形成一个叫Token 的东西。
我在服务器端不保存Token,当客户端把token发过来的时候,我再用同样的算法做一个验证就行了。
如果相同, 我就知道这个人已经登录过了,并且可以直接取到他的user id。
如果不相同, 数据部分肯定被人篡改过,那我就不客气了。
从此以后,我再也不用维护那众多的箱子了,我又回到了最初的美好时光:无状态。
验证token增加了一点儿计算的开销,不过CPU阿甘那傻小子跑得飞快,这点儿计算对他来说不算什么。
不过,所有的事情都是双刃剑。
token很快就遇到了问题
过了一会儿,这个家伙又过来找我了
有了有效期,我就可以检查这个token是否过期了。
可是这小子很执拗,非要立即退出,非要在服务器端让Token立刻失效,有效期不行,气死我了。
被逼急了,我只好在墙上记了一个黑名单
看来,想在服务器端干掉session,干掉状态,几乎不可能啊!
更多精彩技术漫画,尽在码农翻身