小白必读:闲话HTTP短连接中的Session和Token

小白必读:闲话HTTP短连接中的Session和Token

本文引用了刘欣的文章,感谢原作者的分享。

1、引言

Http协议在现今主流的IM系统中拥有无可替代的重要性(在IM系统中用HTTP发起的连接被大家简称为http短连接),但Http作为传统互联网信息交换技术,一些典型的概念比如:Session、Token,对于新手程序员来说很陌生。

很多文章动辄长篇大论、高屋建瓴地从底层协议再到上层分布式应用式的讲解,根本不适合傻白甜程序员,本文的写作目的是以最白话地方式,通俗易懂的为你讲清HTTP协议中的Session和Token等概念,希望读完全文,您仍能满怀信心,继续义无反顾地跳入程序员这个职业深坑 ^_^。更深入的技术细节,请阅读《IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token》。

学习交流:

– 即时通讯开发交流3群:185926912[推荐]

– 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

(本文同步发布于:http://www.52im.net/thread-1686-1-1.html)

2、互联网源起

1990年12月25日,罗伯特·卡里奥在CERN(即位于日内瓦的欧洲原子核研究会)和蒂姆·伯纳斯·李一起成功通过Internet实现了HTTP代理与服务器的第一次通讯(有关HTTP的详细介绍,请见《网络编程懒人入门(六):深入浅出,全面理解HTTP协议》)。蒂姆·伯纳斯·李(Tim Berners-Lee)爵士作为万维网(World Wide Web,简称WWW或互联网)的发明者,被尊称为互联网之父。蒂姆·伯纳斯·李建立的第一个网站(也是世界上第一个网站)是http://info. cern. ch/,它于1991年8月6日上网(即北京时间8月7日)。

▲ 互联网之父——伯纳斯·李(Tim Berners-Lee)

1955年6月8日,伯纳斯·李出生于英格兰伦敦西南部。他的父母都参与了世界上第一台商业电脑,曼切斯特1型(Manchester Mark I)的建造。2017年,他因“发明万维网、第一个浏览器和使万维网得以扩展的基本协议和算法”而获得2016年度的图灵奖,同时还有100万美元奖金(该奖金由谷歌公司提供)。

▲ 图灵奖奖杯实物

在此前的伦敦2012奥运会开幕式上,开幕式总导演丹尼·博伊尔特别为表扬蒂姆·伯纳斯·李爵士的功绩,设计了激动人心的一幕:蒂姆·伯纳斯·李爵士在“伦敦碗”场馆中央用电脑键盘敲出了一句话:This Is For Everyone(为了每一个人)。

媒体评述:“如果蒂姆·伯纳斯-李爵士为互联网申请专利,他将是世界最富有的万亿富豪”。但是,蒂姆·伯纳斯-李爵士将他的发明无偿贡献给全人类。

▲ 蒂姆·伯纳斯·李爵士参与了伦敦奥运2012开幕式的表演

▲ 蒂姆·伯纳斯·李爵士在“伦敦碗”场馆中央用键盘敲下的“This is For Everyone”

▲ 现在的“互联网”已无比庞大

(本图来自:《技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)》一文)

3、相关文章

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

IM开发基础知识补课(一):正确理解前置HTTP SSO单点登陆接口的原理

移动端IM登录时拉取数据如何作到省流量?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

浅谈移动端IM的多点登陆和消息漫游原理

谈谈移动端 IM 开发中登录请求的优化

好了,我们开始正文的阅读。

4、美好的旧时光

我经常想象并怀念三十年前那原始而美好的互联网旧时光, 工作很轻松, 生活很悠闲。

上班的时候偶尔有些HTTP的请求发到我这里, 我简单的看一下, 取出相对应的html文档,图片,发回去就可以了, 然后就可以继续喝茶聊天。

▲ 早期IE浏览器界面

我的创造者们对我很好, 他们制定的一个简单HTTP协议, 就是请求加响应,  尤其是我不用记住是谁刚刚发了HTTP请求,   每个请求对我来说都是全新的!

邮件服务器很羡慕我, 他说:老弟,你的生活太惬意了,  哪像我, 每次有人从客户端访问邮箱, 我都得专门给他建立一个会话, 来处理他发的消息, 你倒好, 完全不用管理会话。

这是由应用的特性决定的, 如果邮件服务器不管理会话, 那多个人之间的邮件消息就会完全混到一起了, 乱作一团了。

而30年前的Web 基本上就是文档的浏览而已, 既然是浏览,我作为一个服务器, 为什么要记住谁在一段时间里都浏览了什么文档呢?

5、是时候该Session出场了

但是好日子没持续多久, 很快大家就不满足于静态的Html 文档了, 交互式的Web应用开始兴起, 尤其是论坛, 在线购物等网站。

我马上就遇到了和邮件服务器一样的问题, 那就是必须管理会话,必须记住哪些人登录系统,  哪些人往自己的购物车中放了商品,  也就是说我必须把每个人区分开。

这对我来说是个不小的挑战, 由于HTTP协议的无状态特性, 我必须加点小手段,才能完成会话管理。

我想出的办法就是给大家发一个会话标识(session id), 说白了就是一个随机的字符串,每个人收到的都不一样,  每次大家向我发起HTTP请求的时候,把这个字符串给一并捎过来, 这样我就能区分开谁是谁了。

6、沉重的负担

大家都很高兴, 可是我就不爽了。

每个人只需要保存自己的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 对我来说是一个沉重的负担。

7、时间换空间:Token是个不错的方案

这几天的晚上我一直在思考, 我为什么要保存这可恶的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开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

从客户端的角度来谈谈移动端IM的消息可靠性和送达机制

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

腾讯技术分享:社交网络图片的带宽压缩技术演进之路

小白必读:闲话HTTP短连接中的Session和Token

IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理

移动端IM中大规模群消息的推送如何保证效率、实时性?

移动端IM开发需要面对的技术问题

开发IM是自己设计协议用字节流好还是字符流好?

请问有人知道语音留言聊天的主流实现方式吗?

IM消息送达保证机制实现(一):保证在线实时消息的可靠投递

IM消息送达保证机制实现(二):保证离线消息的可靠投递

如何保证IM实时消息的“时序性”与“一致性”?

一个低成本确保IM消息时序的方法探讨

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

IM群聊消息如此复杂,如何保证不丢不重?

谈谈移动端 IM 开发中登录请求的优化

移动端IM登录时拉取数据如何作到省流量?

浅谈移动端IM的多点登陆和消息漫游原理

完全自已开发的IM该如何设计“失败重试”机制?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

微信对网络影响的技术试验及分析(论文全文)

即时通讯系统的原理、技术和应用(技术论文)

开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀

QQ音乐团队分享:Android中的图片压缩技术详解(上篇)

QQ音乐团队分享:Android中的图片压缩技术详解(下篇)

腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率

腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)

腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(下篇)

如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(图片压缩篇)

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(音视频技术篇)

为什么说即时通讯社交APP创业就是一个坑?

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-1686-1-1.html)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101603.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 大三度和小三度_大三度和小三度的区别 图解

    大三度和小三度_大三度和小三度的区别 图解转载:https://zhidao.baidu.com/question/297003574.html首先说一下怎么区分大三度与小三度。音程有两个要素,音数和度数。音数指的是音程所的包含全音的数目(

  • hadoop hdfs命令 脚本源码_hadoop启动hdfs命令

    hadoop hdfs命令 脚本源码_hadoop启动hdfs命令hadoop集群搭建好之后,通过HDFS命令操作HDFS分布式文件系统,HDFS命令与linux命令类似所有命令有/bin/hadoop脚本引发,可以使用命令查看帮助文档hadoopfs-help使用HDFS命令之前,必须启动hadoop集群,且命令执行在master节点上

  • matlab norm函数作用_norm值计算

    matlab norm函数作用_norm值计算%X为向量,求欧几里德范数,即。n=norm(X,inf)%求-范数,即。n=norm(X,1)%求1-范数,即。n=norm(X,-inf)%求向量X的元素的绝对值的最小值,即。n=norm(X,p)%求p-范数,即,所以norm(X,2)=norm(X)。命令矩阵的范数函数norm格式n=norm(A)

    2022年10月24日
  • python实现守护进程_linux 守护进程

    python实现守护进程_linux 守护进程什么是守护线程:在后台运行,为其他线程提供服务的线程成为守护线程。为什么要引入守护线程:thread模块不支持守护线程的概念,当主线程退出时,所有的子线程都将终止,不管它们是否仍在工作,如果你不希望发生这种行为,就要引入守护线程的概念。守护线程的调用格式:thread.setDaemon(True)如何使用守护线程:1.当只有一个子线程并且为守护线程,那么这个守护线程就会等待主线程运行完毕后挂掉2…

  • virsh命令行_怎么进入命令行窗口

    virsh命令行_怎么进入命令行窗口[@TOC]定义存储池与其目录创建已定义的存储池激活并自动启动已定义的存储池在存储池中创建虚拟机存储卷kvm存储池主要体现一种管理方式,可以通过挂载存储目录,lvm逻辑卷的方式创建存储池,虚拟机存储卷创建完成后,剩下的操作与无存储卷的方式无任何区别KVM存储池也要用于虚拟机迁移任务存储池相关管理命令二、生产环境存储池使用添加lvm和远程存储即可rawqcowqocw2qed什么是写时拷贝四、挂载磁盘使用libguestfsLinux工具可以在虚拟机无

  • curl命令详解[通俗易懂]

    在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具。它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具。语法:#curl[option][url]常见参数:-A/–user-agent<string>…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号