将浏览器拆成代码,从代码实现层面再聊cookie和session

avatar
作者
筋斗云
阅读量:0

背景

这个东西可能是我十几年前最开始接触的东西,第一次web开始,就是要做登录注册的功能,当时就涉及到cookie和session,用的还是Java,Java 来做Web本身就够晦涩难懂的了,跟更古老的C做Web开发差不了多少(已C语言的方式做了一个Html的字符串输出的模板引擎),即使现在有了SB好了很多, 但也高度封装了底层代码,甚至好多现在Java开发连servlet是啥东西都不知道了。

这篇文章是写给新人的,当然很多老开发者看似懂了,其实也只不过是唯手熟尔,对于底层到底发生了什么,自己能否手敲实现相关的东西,也是一知半解。

为何要了解这种东西?

这是个好问题, 你不了解也没啥大问题,但是你了解了,你能做的事情就比较丰富,而且在定位问题时也会更快,在定制某些东西时也更加灵活,而不是受限于某个框架,某种代码,甚至是某种协议。

Cookie这个东西存在哪?

这个是个老生常谈的问题,初学Web开发的同学,我相信绝对是懵逼的,因为他们无论使用Java,php,python都是在这些代码里面去保存Cookie,而且初学者并没有服务端 和 浏览器端的概念,也不清楚浏览器是个啥,反正就是个上网的东西,怎么渲染出来界面的,为何要请求Ajax等等都不太清楚,因为自己没有部署过远程服务器,大部分人都是搞一个localhost进行调用,还以为一切都发生在本地机器上等等,一堆混杂的概念一股脑全过来,自然脑子里是一团浆糊。

而开始开设课程的人,要么是纯后端,要么是纯前端,总是把这个过程说清楚的,就需要一个全栈技术人员,而且这个全栈还要是科班出身,对计算机网络系统学习过,再能把这堆乱麻理清楚。

再来回答上面这个问题,Cookie存在用户的浏览器的用户目录,什么叫用户目录?

用户目录

  1. 用户目录是每个桌面应用或者移动应用的数据存储位置,因为有了这些数据的存放位置,所有的你访问应用的各种缓存,数据,图片,聊天记录,历史信息等等才能有存放的位置。

  2. 他们一般存放在C盘,而且客户端开发者也懒得让你选,都是走默认路径,而某人路径就是C盘 C:\Users\senzo\AppData\Roaming\WADesk 这个AppData就是用户目录,为什么你的C盘总是被占满,可能因为你装了WPS,缓存了几十G的各类数据导致的,所有的垃圾清理都不会清理用户目录,因为一旦清理了,你的安装的软件就炸了,所以清理软件除非自己不想干了,才会做这个事情。他们只敢清理下垃圾桶和 C:\Users\senzo\AppData\Local\Temp 文件夹,你的浏览器的缓存都存在这里

  1. 谷歌浏览器(其他浏览器一样)也有自己的用户目录,路径一般是 C:\Users\senzo\AppData\Local\Google\Chrome,后面追加一个User Data,这里就存在各种用户文件,我的一篇文件,通过硬链接的方式迁移谷歌用户数据到其他盘,节省C盘空间的文件,也是基于这个原理

  2. https://blog.csdn.net/wangsenling/article/details/131265511

  3. 至于你的Cookie在哪里,10年前我记得是一个txt文件,现在鬼知道Chrome为了安全考虑,把你的Cookie加密后放到哪里了,估计在哪个SQlite里面,不过你知道你的Cookie的存放路径即可,它不是存在一个虚无缥缈的地方,而是一个有一个实际的硬盘存储位置,也不是一直留在内存里,否则你关机后,就消失了。

那我的代码是怎么写Cookie的?

先来看一段PHP代码,当然你可以用ChatGPT翻译成其他语言的

use yii\web\Cookie;  // 假设我们要保存用户的用户名到 Cookie 中 $username = 'exampleUser';  // 获取当前的 response 对象的 cookie 集合 $cookies = Yii::$app->response->cookies;  // 添加一个新的 Cookie $cookies->add(new Cookie([     'name' => 'username',       // Cookie 名称     'value' => $username,       // Cookie 值     'expire' => time() + 86400, // Cookie 过期时间(这里设置为1天) ]));  // 你也可以设置其他的 Cookie 属性,如 'domain', 'httpOnly', 'secure', 等等 

这里你会发现是放在response里面的,response是啥?主流解释就告诉你输出流对象,Java这玩意还跟着Steam这个单词,对于初学者来说,啥是流就是一脸懵逼的。

浏览器向服务器发送的都是request,这个request是有格式的,这个格式是啥?这个格式就是http协议呀,有很多同学一直都觉得是http链接,其实一直都叫错了,连接就是一个概念,这个我之前的文件也讲过,就像我跟谁是好朋友一样,这是一种抽象概念,不是你俩一天到晚肩并肩挨在一起,你们如果是同事关系,那么就要制定一些快速沟通的规则,就像以前的军事情报一样,你瞎写别人是抓不到重点,因此,你自然会这样来编排你的任务

  1. 时间:明天早上8点

  2. 地点:秦岭XXX山,XXX谷设立埋伏

  3. 兵种:步兵,弓箭手,抛石兵

  4. 武器:XXX

  5. 援助:XXX

只有这样,你收到命令之后,才会严格执行,而不会出现差错,同理HTTP就是这样一个通信协议,客户端与服务端的在这种约定俗称之下来回发送数据,进行持续的沟通,再反问一下,连接是什么?连接就是一种概念,元帅和将军的这种保持通信的过程就是连接,所以http不是连接而是一种协议,那么问题来了,还有其他协议不?当然了,ftp不就是另外一种吗?email也是一种呀!

https://blog.csdn.net/wangsenling/article/details/126768328

所以,你的代码将Cookie以协议的方式发给了浏览器,浏览器接收到后,就把它存在了用户目录下面,下次浏览器再发起request请求的时候,就会自动带着Cookie发给服务端,看上面截图的Cookie字段。

Cookie怎么发送给服务端

浏览器咋知道那个服务器要发送那个Cookie呢?

那就是以下这些参数,根据以下参数,浏览器就知道那个domain,那个path下需要跟随Cookie发送了,如果没有设置那就是默认都发

Set-Cookie: session_id=abc123; Domain=example.com; Path=/; Expires=Wed, 21 Aug 2024 07:28:00 GMT; Max-Age=3600; Secure; HttpOnly; SameSite=Strict

服务端又如何根据Cookie找到用户信息的?

  1. 一般Cookie就是一个串,这属于信息压缩的一种,比如微信支付成功后,你想额外在state追加更多东西,于是你想把一个对象json化后回传,对不起,微信支付告诉你state只能有32位长度,怎么破?其实这里传过去的就是一个md5,所有的json内容都被md5之后,在下订单的时候,就发给服务端了,在支付链接的时候,附带这个md5,等支付回调收到这个md5时,再从库里查询具体的对应的一堆数据,就可以完美匹配,而Cookie就是这个原理,Cookie本身就没啥东西,根据这样一个MUID来找到对应的用户信息即可。

Session是什么?

  1. session就是一个概念,如果讲到这里你还不能理解啥叫session,可能就白讲了,session中文翻译为会话,也即服务端根据传过来的MUID,进而从数据库,从redis,从文本文件,从内存等等吧,反正是个能存东西的地方就可以,通过uid来提取用户的信息即可。

  2. 那为何不用uid来搞事情?用uid那不是你纯靠蒙都能登录用户的账号了

  3. 那多账号怎么管理的?切换账号的时候,重新写入MUID呗,可惜的是,服务端如果设置了httpOnly,那浏览器是无法重置的,所以你也很少看到一个浏览器可以控制多个账号的逻辑,有的也是用token的方式,手动变换Token,来切换不同账号

总结

  1. 搞懂上面这些概念后,你就知道session可以设置哪些东西,只要是用户特异性东西都应该存放在这里,Electron开发中,就有session的概念,这个session就是对应着一个webview,或者一个window.webContent,两者绑定在一起,就能将一个webview或者一个webContent对应一个用户的数据,实现了用户数据的隔离,另外,你还可以在这个基础上进一步推测,session还有哪些可以设置的东西,这样即使你不学习session,也能猜出来session是干啥的。

  2. 此外,b/s 在你眼里就变成了一个代码式的ajax请求,发送数据,返回数据,浏览器拿到了html这种配置文件就会帮你渲染成UI界面,至于里面的图片,js,视频等等都是浏览器再帮你发送请求进行一点点的数据处理,来回反复请求,只不过这个过程给你的感觉,好像是同时发生的,你好像觉得html发送给浏览器后,浏览器就不用干任何事情了,实际上你观察network下的fetch/xhr,ws等通信就会发现,浏览器在拿到html后,就会不断地向服务器请求各种资源,也就是不断地发送http协议请求,来回保持这种通信。

  3. 至此,你就打通了,代码http通信和浏览器通信和渲染的联系,在你眼里,浏览器所做的一切,都是http协议的下的来回通信,来回数据拉取,因此你也就大概知道了,自己如何开发一个浏览器客户端。

  4. 当然,你开发浏览器就别想了,这是一个庞大的工程,微软都顶不住,还何况一个个人,不过机理,你掌握了,那其实你可以做的,改的,搞的事情就非常非常多了。

    广告一刻

    为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!