HTTP Cookie
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 请求,也就是连着发送了两次请求。