本文引用了刘欣的文章,感谢原做者的分享。php
Http协议在现今主流的IM系统中拥有无可替代的重要性(在IM系统中用HTTP发起的链接被你们简称为http短链接),但Http做为传统互联网信息交换技术,一些典型的概念好比:Session、Token,对于新手程序员来讲很陌生。html
不少文章动辄长篇大论、高屋建瓴地从底层协议再到上层分布式应用式的讲解,根本不适合傻白甜程序员,本文的写做目的是以最白话地方式,通俗易懂的为你讲清HTTP协议中的Session和Token等概念,但愿读彻底文,您仍能满怀信心,继续义无反顾地跳入程序员这个职业深坑 ^_^。更深刻的技术细节,请阅读《IM开发基础知识补课(四):正确理解HTTP短链接中的Cookie、Session和Token》。程序员
学习交流:算法
- 即时通信开发交流3群:185926912[推荐]编程
- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》浏览器
(本文同步发布于:http://www.52im.net/thread-1686-1-1.html)安全
1990年12月25日,罗伯特·卡里奥在CERN(即位于日内瓦的欧洲原子核研究会)和蒂姆·伯纳斯·李一块儿成功经过Internet实现了HTTP代理与服务器的第一次通信(有关HTTP的详细介绍,请见《网络编程懒人入门(六):深刻浅出,全面理解HTTP协议》)。蒂姆·伯纳斯·李(Tim Berners-Lee)爵士做为万维网(World Wide Web,简称WWW或互联网)的发明者,被尊称为互联网之父。蒂姆·伯纳斯·李创建的第一个网站(也是世界上第一个网站)是http://info. cern. ch/,它于1991年8月6日上网(即北京时间8月7日)。服务器
1955年6月8日,伯纳斯·李出生于英格兰伦敦西南部。他的父母都参与了世界上第一台商业电脑,曼切斯特1型(Manchester Mark I)的建造。2017年,他因“发明万维网、第一个浏览器和使万维网得以扩展的基本协议和算法”而得到2016年度的图灵奖,同时还有100万美圆奖金(该奖金由谷歌公司提供)。微信
在此前的伦敦2012奥运会开幕式上,开幕式总导演丹尼·博伊尔特别为表扬蒂姆·伯纳斯·李爵士的功绩,设计了激动人心的一幕:蒂姆·伯纳斯·李爵士在“伦敦碗”场馆中央用电脑键盘敲出了一句话:This Is For Everyone(为了每个人)。网络
媒体评述:“若是蒂姆·伯纳斯-李爵士为互联网申请专利,他将是世界最富有的万亿富豪”。可是,蒂姆·伯纳斯-李爵士将他的发明无偿贡献给全人类。
(本图来自:《技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)》一文)
《IM开发基础知识补课(四):正确理解HTTP短链接中的Cookie、Session和Token》
好了,咱们开始正文的阅读。
我常常想象并怀念三十年前那原始而美好的互联网旧时光, 工做很轻松, 生活很清闲。
上班的时候偶尔有些HTTP的请求发到我这里, 我简单的看一下, 取出相对应的html文档,图片,发回去就能够了, 而后就能够继续喝茶聊天。
个人创造者们对我很好, 他们制定的一个简单HTTP协议, 就是请求加响应, 尤为是我不用记住是谁刚刚发了HTTP请求, 每一个请求对我来讲都是全新的!
邮件服务器很羡慕我, 他说:老弟,你的生活太惬意了, 哪像我, 每次有人从客户端访问邮箱, 我都得专门给他创建一个会话, 来处理他发的消息, 你倒好, 彻底不用管理会话。
这是由应用的特性决定的, 若是邮件服务器无论理会话, 那多我的之间的邮件消息就会彻底混到一块儿了, 乱做一团了。
而30年前的Web 基本上就是文档的浏览而已, 既然是浏览,我做为一个服务器, 为何要记住谁在一段时间里都浏览了什么文档呢?
可是好日子没持续多久, 很快你们就不知足于静态的Html 文档了, 交互式的Web应用开始兴起, 尤为是论坛, 在线购物等网站。
我立刻就遇到了和邮件服务器同样的问题, 那就是必须管理会话,必须记住哪些人登陆系统, 哪些人往本身的购物车中放了商品, 也就是说我必须把每一个人区分开。
这对我来讲是个不小的挑战, 因为HTTP协议的无状态特性, 我必须加点小手段,才能完成会话管理。
我想出的办法就是给你们发一个会话标识(session id), 说白了就是一个随机的字符串,每一个人收到的都不同, 每次你们向我发起HTTP请求的时候,把这个字符串给一并捎过来, 这样我就能区分开谁是谁了。
你们都很高兴, 但是我就不爽了。
每一个人只须要保存本身的session id,而我须要保存全部人的session id ! 若是访问个人人多了, 就得由成千上万,甚至几十万个。
这对我来讲是一个巨大的开销 , 严重的限制了个人扩展能力, 好比说我用两个机器组成了一个集群, 小F经过机器A登陆了系统, 那session id会保存在机器A上, 假设小F的下一次请求被转发到机器B怎么办? 机器B可没有小F的 session id啊。
有时候我会采用一点小伎俩: session sticky , 就是让小F的请求一直粘连在机器A上, 可是这也无论用, 要是机器A挂掉了, 还得转到机器B去。
那我只好作session 的复制了, 把session id 在两个机器之间搬来搬去, 快累死了。
后来有个叫Memcached的给我支了招: 把session id 集中存储到一个地方, 全部的机器都来访问这个地方的数据, 这样一来,就不用复制了, 可是增长了单点失败的可能性, 要是那个负责session 的机器挂了, 全部人都得从新登陆一遍, 估计得被人骂死。
我也尝试把这个单点的机器也搞出集群,增长可靠性, 但无论如何, 这小小的session 对我来讲是一个沉重的负担。
这几天的晚上我一直在思考, 我为何要保存这可恶的session呢, 只让每一个客户端去保存该多好?
但是若是我不保存这些session id , 我怎么验证客户端发给个人session id 的确是我生成的呢? 若是我不去验证,我都不知道他们是否是合法登陆的用户, 那些不怀好意的家伙们就能够伪造session id , 随心所欲了。
嗯,对了,关键点就是验证 !
好比说, 小F已经登陆了系统, 我给他发一个令牌(token), 里边包含了小F的 user id, 下一次小F 再次经过Http 请求访问个人时候, 把这个token 经过Http header 带过来不就能够了。
不过这和session id没有本质区别啊, 任何人均可以能够伪造, 因此我得想点儿办法, 让别人伪造不了。
那就对数据作一个签名吧, 好比说我用HMAC-SHA256 算法,加上一个只有我才知道的密钥, 对数据作一个签名, 把这个签名和数据一块儿做为token , 因为密钥别人不知道, 就没法伪造token了。
这个token 我不保存, 当小F把这个token 给我发过来的时候,我再用一样的HMAC-SHA256 算法和一样的密钥,对数据再计算一次签名, 和token 中的签名作个比较, 若是相同, 我就知道小F已经登陆过了,而且能够直接取到小F的user id , 若是不相同, 数据部分确定被人篡改过, 我就告诉发送者: 对不起,没有认证。
Token 中的数据是明文保存的(虽然我会用Base64作下编码, 但那不是加密), 仍是能够被别人看到的, 因此我不能在其中保存像密码这样的敏感信息。
固然, 若是一我的的token 被别人偷走了, 那我也没办法, 我也会认为小偷就是合法用户, 这其实和一我的的session id 被别人偷走是同样的。
这样一来, 我就不保存session id 了, 我只是生成token , 而后验证token , 我用个人CPU计算时间获取了个人session 存储空间 !
解除了session id这个负担, 能够说是无事一身轻, 个人机器集群如今能够轻松地作水平扩展, 用户访问量增大, 直接加机器就行。这种无状态的感受实在是太好了!
《移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》
《移动端IM开发者必读(二):史上最全移动弱网络优化方法总结》
《现代移动端网络短链接的优化手段总结:请求速度、弱网适应、安全保障》
《小白必读:闲话HTTP短链接中的Session和Token》
《IM开发基础知识补课:正确理解前置HTTP SSO单点登录接口的原理》
《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》
《开源IM工程“蘑菇街TeamTalk”的现状:一场虎头蛇尾的开源秀》
《QQ音乐团队分享:Android中的图片压缩技术详解(上篇)》
《QQ音乐团队分享:Android中的图片压缩技术详解(下篇)》
《腾讯原创分享(一):如何大幅提高移动网络下手机QQ的图片传输速度和成功率》
《腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)》
《腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(下篇)》
《如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源》
《基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?》
《腾讯技术分享:腾讯是如何大幅下降带宽和网络流量的(图片压缩篇)》
《腾讯技术分享:腾讯是如何大幅下降带宽和网络流量的(音视频技术篇)》
>> 更多同类文章 ……
(本文同步发布于:http://www.52im.net/thread-1686-1-1.html)