多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## HTTP 邮件服务器必须得管理会话,因为如果不管理的话,多个人的邮件就混到一起去了。 但是很早之前的Web基本上就是文档的浏览而已,服务器根本不需要记住谁在一段时间里浏览了什么文档。 ## Session 后来大家不满足静态的HTML文档了,交互式的Web开始兴起。 此时Web服务器必须管理会话,必须知道哪些人登录了系统,哪些人往自己的购物车里面放了东西。 由于HTTP协议的无状态特性,必须曲线救国 可以给每个人发一个会话标识session id,也就是一个随机字符串,当浏览器发起HTTP请求的时候,会把这个session id一起带过来,就可以区分谁是谁了。 ## 沉重的负担 使用session id的坏处在于,服务器需要保存所有人的session id。 这是巨大的开销,严重限制了扩展能力,比如说两个机器组成了集群,一个人通过机器A登录了系统,那么session id会保存在机器A上,但是如果下一次请求发到了机器B怎么办? 于是可以使用session sticky。也就是说这个人的请求一直都只转发到机器A上。 那么机器A如果挂了怎么办? 只要做session 复制了,这样又涉及到session id在两个机器之间搬来搬去 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180830091805.png?picgo) 后来Memcached将session id放到一个地方,所有机器都来访问这个地方的数据。 但是又增加了单点失败的可能性。 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180830091939.png?picgo) 如果不存储session id的机器又搞出个集群,感觉对一个小小的session 还杀鸡用牛刀 ## 时间换空间 那么Web服务器可以不保存session吗? 但是如果不保存session,如何验证客户端发过来的session id是服务器生成的,而非伪造的呢? 所以关键点在于验证。 比如说一个人登录了系统,就可以给他发一个token,这个token需要包含这个人的user id 。 下次这个人再访问服务器的时候,可以把这个token顺道带过来。 但是依然没有解决易被伪造的问题。 那么就可以对数据做一个签名,比如使用HMAC-SHA256算法,加上一个不公开的密钥,可以对数据做签名。 这个签名与数据放在一起做为token 只要保管好了token,别人就无法伪造。 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180830092732.png?picgo) 所以服务器不需要保存token,当人们把 token发过来的时候,可以使用SHA256算法+密钥,再对数据重新计算一次,并与token 中的签名做比较。 如果相同,则说明一定登录过了。 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180830093015.png?picgo) Token 中的数据是明文保存的,所以不能在其中保存像密码那样的敏感信息 如果token被偷走了,也没有办法,这和一个人的session id被偷走了一样。 总之,服务器是使用CPU计算时间来获取了session 的存储空间。 这样,机器集群可以轻松做水平扩展,用户量增大,直接加机器即可。