💓博主CSDN主页:杭电码农-NEO💓
⏩专栏分类:Linux从入门到精通⏪
🚚代码仓库:NEO的学习日记🚚
🌹关注我🫵带你学更多操作系统知识
🔝🔝
Linux拓展
1. 前言
你是否注意到这样一种情况, 当你在网页登录了B站后, 第二天再打开B站, 你会发现你还是处于登录状态, 你好奇这是怎么做到的吗? 答案是用cookie做到的
本章重点:
本篇文章会讲解cookie, session, token的概念, 区别以及使用场景.
2. 初识cookie
HTTP Cookie(也称为 Web Cookie、浏览器 Cookie 或简称 Cookie)是服务器发送到用户浏览器并保存在浏览器上的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态、记录用户偏好等。
cookie的工作原理
- 在浏览器上首次访问B站时, 会进行登录(注册)请求
- 服务器收到此请求后, 会通过HTTP的头信息: SET-Cookie, 将用户信息(账号密码)返回给用户
- 用户会将服务器返回的用户信息, 保存在内存或磁盘当中
- 下次用户向服务器发送请求时, 会自动携带已保存的信息
cookie分类实操
cookie信息会被保存到内存或磁盘, 所以cookie其实分为内存级和文件级.
- 内存级的cookie会在浏览器关闭时, 自动释放
- 文件级的cookie会在本地文件中保存(可设置过期时间)
在浏览器的左上方有cookie信息:
一旦你将B站这个页面的cookie信息全部删除掉, 那么当你下次打开B站网页时, 就不会自动登录了!
3. cookie实操演示
由于实操cookie需要利用套接字自主实现一个HTTP服务器,这里我直接找了一个现成的服务器代码来进行演示. 考虑到有些同学并不是比特的学生, 这里我把代码copy一份到我自己的仓库: cookie示例代码
- HTTP 存在一个报头选项:Set-Cookie, 可以用来进行给浏览器设置 Cookie值。
- 在 HTTP 响应头中添加,客户端(如浏览器)获取并自行设置并保存Cookie。
格式:
Set-Cookie:<name>=<value>
其中 <name> 是 Cookie 的名称,<value> 是 Cookie 的值。
设置包头
假设要给客户端返回的cookie信息为: user:zhangsan,就可以在HTTP的包头位置添加下面的语句
"Set-Cookie: username=zhangsan;"
假设你想要返回两个信息字段: user:zhangsan, passwd:123456. 可以这样写
"Set-Cookie: username=zhangsan;""Set-Cookie: passwd=123456;"
cookie是key-value形式的,要设置多个值需要在HTTP包头中设置多行
看上面的图片,相信你也发现了, cookie不仅仅可以存储key-value信息, 还可以存储路径, 到期时间等. 下面就来讲解这两个特殊参数. 首先, 如果将路径设置为’/',代表此cookie信息, 在访问此服务器的任意资源时, 都会被带上. 而假设你的路径设置为/a/b. 那么只有当你访问服务器下的/a/b这个资源时, 才会带上这个cookie信息. 这是他们区别
路径参数的设置方法
假设你想要设置路径为/a/b
"Set-Cookie: username=zhangsan; path=/a/b;"
假设你想要设置路径为/
"Set-Cookie: passwd=123456; path=/;"
cookie到期时间设置方法
cookie的到期时间的设置比较复杂, 要遵循特殊的时间格式(比如格林威治时间).这里罗列出简单的格式, 大家可以下来自行验证
"Set-Cookie: username=peter; expires=Thu, 18 Dec 2024 12:00:00UTC; path=/;"
时间格式必须遵守 RFC 1123 标准,具体格式样例
expires=Tue, 01 Jan 2030 12:34:56 GMT 或者 UTC(推荐)
关于时间解释
- expires是固定写法
- Tue: 星期二(星期几的缩写)
- ,: 逗号分隔符
- 01: 日期(两位数表示)
- Jan: 一月(月份的缩写)
- 2030: 年份(四位数)
- 12:34:56: 时间(小时、分钟、秒
- GMT: 格林威治标准时间(时区缩写)
4. 认识session
使用cookie来保持用户的登录状态确实很方便. 但是会有一些安全问题摆在面前: cookie中, 用户的敏感信息, 如: 用户账号密码等, 是保存在用户的电脑本地的. 大部分的用户都是程序小白, 他们可不知道自己的私密信息在哪里. 但是黑客却知道. 如果用户点击了某些钓鱼网站, 很有可能黑客会盗取了用户存储在本地的私密信息, 并且使用此cookie信息来登录各个网站. 存在安全风险, 所以才有了session的出现!!!
session的定义
HTTP Session 是服务器用来跟踪用户与服务器交互期间用户状态的机制。由于 HTTP协议是无状态的(每个请求都是独立的),因此服务器需要通过 Session 来记住用户的信息
session工作原理
- 用户登录(注册)B站信息时, 会将用户信息: 账号密码, 打包发送给服务器
- 服务器收到用户信息后, 会将此信息存储在服务器本地(内存或磁盘)
- 之后, 服务器会生成一个全局唯一的ID: session id, 并通过HTTP的cookie字段发给客户端
- 客户端收到此session id后, 会将此信息存储在磁盘或内存
- 客户端在之后的每一次请求中,都会带上这个session id
你可能会问, session id不是还在用户本地吗? 这为啥就安全了呢? 其实session并不是完全的安全, 黑客当然可以直接拿到你的session id再冒充你的身份去登录, 但是这里的安全性体现在, 黑客无法直接获取到你的账号密码等私密信息, 比如咱们QQ若使用cookie, 黑客可以直接盗取你的账号密码去完成登录, 但是若黑客只是拿到session id, 那么它就需要去利用session id来冒充你的身份, 当然! 像腾讯这种企业的安全性防护是做的很好的, 假如你盗取了session id去进行登录, 可能会识别到你的机器IP和此账号经常登录的IP不符号, 可能会让你进行手机号验证等等. 总之, session确实是一定程度上保证了安全性(具体的安全操作,要根据不同的业务来进行调整)
5. 认识token
为啥有了session后,还要有token? 不知道你有没有想过这样的场景, 某些大型服务, 比如淘宝, 它提供的不同的功能可能是在不同服务器中实现的, 将多个服务器的功能拼接到一起, 形成完整的淘宝服务, 这也就是名为常说的分布式系统. 如果在分布式系统中使用session会有什么问题呢? 相信聪明的你已经想到了, 由于session信息是保存在服务器本地的, 若一个分布式系统中, 只有一个服务器保存了session信息, 当其他服务器收到请求后是无法进行身份快速验证的. 于是在分布式系统中, 每台服务器都需要存储一份相同的session信息, 非常浪费空间!!!
token的定义
Token(通常指 JSON Web Token,JWT)是一种用于在网络应用中进行身份验证和授权的机制. token是一个包含用户信息和签名的密钥字符串(JWT字符串), 由三个部分组成: header(包含算法和token类型), payload(数据本身)和signature(验证密钥)
token的工作原理
- 浏览器发起请求后, 服务器认证成功后会创建一个JWT字符串(包含三段信息)
- 同时,服务器会生成一个只有服务器自己知道的密钥
- 服务器将创建好的JWT字符串(也就是所谓的token)返回给浏览器
- 浏览器会将此token保存在本地, 后续请求时会带上此token
使用token之后,服务器就不需要再保存任意大量的数据了,数据都在token字符串中, 只需要进行安全验证后, 自己去对token解密即可拿到对应的信息,这种方式在分布式系统中可比session好用多了
**
其实关于token的验证部分是很有趣的,为什么服务器能验证出token没有被篡改?有兴趣的同学可以下去了解一下
**
6. 总结
不论是cookie, session还是token, 他们本质上都是用于在 Web 应用中管理用户状态和身份验证的技术, 他们的优缺点相信大家心里都有数了, 实际场景下如何选择使用哪种方案, 就得靠你自己了!
版权归原作者 杭电码农-NEO 所有, 如有侵权,请联系我们删除。