HTTP Cookie 和 session

HTTP协议本身是无状态,无连接的。

无状态是指,客户每次发起请求,服务器都不认识客户是谁,它只会根据请求返回对应的资源响应。

无连接不是指TCP的无连接,通常指的是HTTP协议本身不在请求和响应之间维护任何状态(这是无状态的含义),而不是指它不使用TCP连接。HTTP的"无连接"特性更多是指每次请求/响应交换都是独立的,且不需要在请求之间维护连接状态。

定义

HTTP Cookie (也称为 Web Cookie 、浏览器 Cookie 或简称 Cookie )是服务器发送到
用户浏览器并保存在浏览器上的一小块数据,它会在浏览器之后向同一服务器再次发
起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一
浏览器,如保持用户的登录状态、记录用户偏好等。

工作原理

当用户第一次访问网站时,服务器会在响应的 HTTP 头中设置 Set-Cookie
字段,用于发送 Cookie 到用户的浏览器。

浏览器在接收到 Cookie 后,会将其保存在本地(通常是按照域名进行存
储)。

在之后的请求中,浏览器会自动在 HTTP 请求头中携带 Cookie 字段,将之
前保存的 Cookie 信息发送给服务器。

关于Cookie的分类

会话 Cookie ( Session Cookie ) :在浏览器关闭时失效。

持久 Cookie ( Persistent Cookie ) :带有明确的过期日期或持续时间,
可以跨多个浏览器会话存在。

如果 cookie 是一个持久性的 cookie ,那么它其实就是浏览器相关的,特
定目录下的一个文件。但直接查看这些文件可能会看到乱码或无法读取的内容,
因为 cookie 文件通常以二进制或 sqlite 格式存储。一般我们查看,直接在浏览
器对应的选项中直接查看即可。

会话级别其实也就是内存级别,浏览器启动了也是了一个程序,把程序关闭了,和它相关的内存数据自然也就被释放了。

安全性

由于 Cookie 是存储在客户端的,因此存在被篡改或窃取的风险。

用途

用户认证和会话管理 ( 最重要 )

跟踪用户行为

缓存用户偏好等

比如在 chrome 浏览器下,可以直接访问: chrome://settings/cookies

认识Cookie

HTTP 存在一个报头选项: Set-Cookie , 可以用来进行给浏览器设置 Cookie
值。

在 HTTP 响应头中添加,客户端(如浏览器)获取并自行设置并保存
Cookie 。

基本格式:

cpp 复制代码
Set-Cookie: <name>=<value>
其中 <name> 是 Cookie 的名称,<value> 是 Cookie 的值

一个完整的Cookie格式

cpp 复制代码
Set-Cookie: username=peter; expires=Thu, 18 Dec 2024 12:00:00
UTC; path=/; domain=.example.com; secure; HttpOnly

注意:这只是一个Cookie,在username=peter后跟的都是这一条Cookie的属性。

可以设置多个Cookie,那么就要重新加一条,比如 Set-Cookie:passwd=123;XXXXX
时间格式必须遵守 RFC 1123 标准,具体格式样例: Tue, 01 Jan 2030 12:34:56
GMT 或者 UTC( 推荐 ) 。

计算方式: GMT 基于地球的自转和公转,而 UTC 基于原子钟。

准确度:由于 UTC 基于原子钟,它比基于地球自转的 GMT 更加精确。
在实际使用中, GMT 和 UTC 之间的差别通常很小,大多数情况下可以互换使用。但
在需要高精度时间计量的场合,如科学研究、网络通信等, UTC 是更为准确的选择。

关于这些属性的说明:

expires=<date> [ 要验证 ] :设置 Cookie 的过期日期 / 时间。如果未指定此属
性,则 Cookie 默认为会话 Cookie ,即当浏览器关闭时过期。(重要)

path=<some_path> [ 要验证 ] :限制 Cookie 发送到服务器的哪些路径。默认
为设置它的路径。(重要)

domain=<domain_name> [ 了解即可 ] :指定哪些主机可以接受该 Cookie 。默
认为设置它的主机。

secure [ 了解即可 ] :仅当使用 HTTPS 协议时才发送 Cookie 。这有助于防止
Cookie 在不安全的 HTTP 连接中被截获。

HttpOnly [ 了解即可 ] :标记 Cookie 为 HttpOnly ,意味着该 Cookie 不能被
客户端脚本(如 JavaScript )访问。这有助于防止跨站脚本攻击( XSS )

注意事项

每个 Cookie 属性都以分号( ; )和空格( )分隔。

名称和值之间使用等号( = )分隔。

如果 Cookie 的名称或值包含特殊字符(如空格、分号、逗号等),则需要
进行 URL 编码。

在我们手动设置Cookie属性,在设置时间属性的时候,有一个函数是将时间戳转化成为一个struct tm的结构体,里面有年月日等信息,但是在这里转化函数不能用localtime,要用

cpp 复制代码
struct tm *tm = gmtime(&timeout);

因为localtime是默认自带了时区的,gmtime获取的是统一的UTC统一时间。

Cookie的生命周期

如果设置了 expires 属性,则 Cookie 将在指定的日期 / 时间后过期。

如果没有设置 expires 属性,则 Cookie 默认为会话 Cookie ,即当浏览器
关闭时过期

安全性的考虑

使用 secure 标志可以确保 Cookie 仅在 HTTPS 连接上发送,从而提高安
全性。

使用 HttpOnly 标志可以防止客户端脚本(如 JavaScript )访问 Cookie ,
从而防止 XSS 攻击。

然而现在一般都不只是单独使用Cookie了,因为Cookie它也可能会将用户的私密信息,比如浏览记录,账号密码,容易被其他人盗取,如果没有进行加密的话,还有导致这些私密的信息被泄露。

信息被泄露,这才是最严重的。

HTTP session

定义

HTTP Session 是服务器用来跟踪用户与服务器交互期间用户状态的机制。由于 HTTP
协议是无状态的(每个请求都是独立的),因此服务器需要通过 Session 来记住用户
的信息。

浅谈原理

因为Cookie把用户信息保存在客户端,所以信息很容易被泄露。于是就有了如上,用户拿着账号和密码进行登录,服务器验证完信息后,会通过算法形成一个唯一的sessionID,这个sessionID指向了一个session对象,这个对象里面保存的就是用户的账号密码,还有各种用户信息,然后在返回给用户的时候,setCookie就只有一个 sessionID了。

那么用户下次访问,就只需要用sessionID给服务器即可,这样就算用户的数据被盗取了,对方也只能冒充用户登录,用户只需要更改密码,原来的sessionID就失效了,最重要的是用户的信息就不会被泄露了。

并且对于用户被冒充这种情况,服务器其实有很多的解决方法,最简单粗暴的方式就是直接让这个sessionID失效即可。服务器可以通过识别该session的行为,比如它的行为突然变得异常,或者是登录位置突然发生了转变,在识别这是一个异常session后,通过直接释放session对象的方式,直接让sessionID失效。

所以总结:

使用session,可以基本解决用户信息被泄露的问题,因为用户此时的信息已经保存在服务器上了;使用session,可以解决大部分用户被冒充登录的问题,因为服务器可以通过检测session的行为或者登录位置来判断是否是非法session,如果是非法的,那么服务器可以直接让该session失效。

拓展
favicon.ico 是一个网站图标,通常显示在浏览器的标签页上、地址栏旁边或收
藏夹中。这个图标的文件名 favicon 是 "favorite icon" 的缩写,而 .ico 是图标的文
件格式。

浏览器在发起请求的时候,也会为了获取图标而专门构建 http 请求,也就是连着发送了两次请求。

相关推荐
Karoku06615 分钟前
【网站架构部署与优化】web服务与http协议
linux·运维·服务器·数据库·http·架构
geek_Chen0117 分钟前
虚拟机共享文件夹开启后mnt/hgfs/下无sharefiles? --已解决
linux·运维·服务器
(⊙o⊙)~哦1 小时前
linux 解压缩
linux·运维·服务器
掘根2 小时前
【网络】高级IO——poll版本TCP服务器
网络·数据库·sql·网络协议·tcp/ip·mysql·网络安全
友友马3 小时前
『 Linux 』HTTP(一)
linux·运维·服务器·网络·c++·tcp/ip·http
2401_872514973 小时前
深入探究HTTP网络协议栈:互联网通信的基石
网络·网络协议·http
重生之我在20年代敲代码4 小时前
HTML讲解(一)body部分
服务器·前端·html
清水白石0084 小时前
C++使用Socket编程实现一个简单的HTTP服务器
服务器·c++·http
GG_Bond194 小时前
【项目设计】Facial-Hunter
服务器·人工智能
Tak1Na5 小时前
2024.9.18
linux·运维·服务器