🌮 定义
🔥HTTP Cookie(也称为 Web Cookie、 浏览器 Cookie 或简称 Cookie,中文意思为 “曲奇饼,小甜饼”) 是服务器发送到用户浏览器并保存在浏览器上的一小块数据, 它会在浏览器之后向同一服务器再次发起请求时被携带并发送到服务器上。 通常, 它用于告知服务端两个请求是否来自同一浏览器, 如保持用户的登录状态、 记录用户偏好等。
🧀 工作原理
在之后的请求中, 浏览器会 自动在 HTTP 请求头 中携带 Cookie
字段, 将之前保存的 Cookie 信息发送给服务器。
🦋 分类
如果 cookie 是一个持久性的 cookie, 那么它其实就是浏览器相关的, 特定目录下的一个文件。 但直接查看这些文件可能会看到乱码或无法读取的内容,因为 cookie 文件通常以二进制或 sqlite 格式存储。 一般我们查看, 直接在浏览器对应的选项中直接查看即可。
如下:
🦋 安全性
🦋 用途
服务器将 Cookie 返回给浏览器, 客户端(浏览器)这边就会通过
Cookie
保存当前用户的状态,当客户端访问服务器时,就会自动把 Cookie 内容带入到请求中,服务器接收到之后,就能知道当前客户是谁,现在客户端处于什么状态了,当前客户的服务提供到哪个环节了。Cookie 就像是 服务器在客户端搞的一个寄存处一样。
Cookie 就是浏览器给页面提供的一种能持久化存储数据的机制。
Cookie值
Cookie
Set-Cookie: <name>=<value>
其中 <name> 是 Cookie 的名称, <value> 是 Cookie 的值。
完整格式如下:
Set-Cookie: username=peter; expires=Thu, 18 Dec 2024 12:00:00 UTC; path=/; domain=.example.com; secure; HttpOnly
Cookie 组成
Cookie 的组织形式
🧑💻 时间格式必须遵守 RFC 1123 标准, 具体格式样例: Tue, 01 Jan 2030 12:34:56 GMT
或者 UTC(推荐)。
🥑 关于时间解释
🦁 GMT(格林威治标准时间) VS UTC(协调世界时) 两者是两个不同的时间标准, 但它们在大多数情况下非常接近, 常常被混淆。 以下是两者的简单解释和区别:
区别:
🧑💻 在实际使用中, GMT 和 UTC 之间的差别通常很小, 大多数情况下可以互换使用。 但在需要高精度时间计量的场合, 如科学研究、 网络通信等, UTC 是更为准确的选择。
💢 生成 UTC 代码如下:
std::string GetMonthName(int month)
{
std::vector<std::string> months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
return months[month];
}
std::string GetWeekDayName(int day)
{
std::vector<std::string> weekdays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
return weekdays[day];
}
std::string ExpireTimeUseRfc1123(int t) // 秒级别的未来UTC时间
{
time_t timeout = time(nullptr) + t;
struct tm *tm = gmtime(&timeout); // 这里不能用localtime,因为localtime是默认带了时区的. gmtime获取的就是UTC统一时间
char timebuffer[1024];
//时间格式如: expires=Thu, 18 Dec 2024 12:00:00 UTC
snprintf(timebuffer, sizeof(timebuffer), "%s, %02d %s %d %02d:%02d:%02d UTC",
GetWeekDayName(tm->tm_wday).c_str(),
tm->tm_mday,
GetMonthName(tm->tm_mon).c_str(),
tm->tm_year+1900,
tm->tm_hour,
tm->tm_min,
tm->tm_sec
);
return timebuffer;
}
单独使用 Cookie, 有什么问题?
如何提高 Cookie 的安全性?
HttpOnly
设为 true
,那么该 Cookie 将只能通过 HTTP 或 HTTPS 协议访问,而不能通过 JavaScript 或其他客户端脚本访问, 防止其他恶意脚本访问 Cookie 盗取信息.Secure
设为 true
,只通过 HTTPS 等安全连接发送时才会被浏览器发送到服务器, 防止其他恶意网站窃取 Cookie 信息.注意: 上面这些设置都是服务器设置的,因为 Cookie 本身就是 服务器返回给浏览器,浏览器只是简单的进行了存储.
🧑💻 关于其他可选属性的解释
属性名 | 作用 |
---|---|
expires=[要验证] | 设置 Cookie 的过期日期/时间。 如果未指定此属性, 则 Cookie 默认为会话 Cookie, 即当浏览器关闭时过期。 |
path=<some_path>[要验证] | 限制 Cookie 发送到服务器的哪些路径。 默认为设置它的路径。 |
domain=<domain_name> [了解即可] | 指定哪些主机可以接受该 Cookie。 默认为设置它的主机。 |
secure [了解即可] | 仅当使用 HTTPS 协议时才发送 Cookie。 这有助于防止 Cookie 在不安全的 HTTP 连接中被截获。 |
HttpOnly [了解即可]: | 标记 Cookie 为 HttpOnly, 意味着该 Cookie 不能被客户端脚本(如 JavaScript) 访问。 这有助于防止跨站脚本攻击(XSS) 。 |
💢注意事项
🐻 Cookie有哪些缺陷 ?
Cookie 的生命周期
expires
属性, 则 Cookie 将在指定的日期/时间后过期。expires
属性, 则 Cookie 默认为会话 Cookie
, 即当浏览器关闭时过期。💦 HTTP Session
是服务器用来跟踪用户与服务器交互期间用户状态的机制。 由于 HTTP 协议是无状态的(每个请求都是独立的) , 因此服务器需要通过 Session 来记住用户的信息。
“无状态” 的含义指的是:
上面的令牌通常就是服务器以 Cookie 形式返回给浏览器, 服务器存储的用户信息对应的就是 Session。通常情况下,一个用户关联一个 Session (会话)。
打个比方:去医院看病.
💫 服务器这边就需要记录令牌信息, 以及令牌对应的用户信息, 这个就是 Session
机制所做的工作.
会话的本质就是一个 “哈希表”, 存储了一些键值对结构. key 就是令牌的 ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计).
session ID
是由服务器生成的一个 “唯一性字符串”, 又叫 token
Session ID
, 并通过 Cookie 将其发送到客户端 (例如通过 HTTP 响应中的 Set-Cookie 字段返回)。Session ID
, 服务器通过 Session ID
来识别用户, 从而获取用户的会话信息。Session
也有过期时间。(Session 的默认过期时间30分钟)🐇 安全性:
🐇 超时和失效:
🐇 用途:
联系:在网站的登录功能中,Cookie 与 Session 一般需要配合使用
web开发发展至今,cookie和session的使用已经出现了一些非常成熟的方案。在如今的市场或者企业里,一般有两种存储方式:
cookie
存储一个 session_id
,然后具体的数据则是保存在session
中。如果用户已经登录,则服务器会在 cookie
中保存一个 session_id
,下次再次请求的时候,会把该 session_id
携带上来,服务器根据 session_id
在 session
库中获取用户的 session
数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做 server side session
。session
数据加密,然后存储在 cookie
中。这种专业术语叫做 client side session
。flask采用的就是这种方式,但是也可以替换成其他形式。区别:
安全与性能问题
所以:将登陆信息等重要信息存放为 session
;其他信息如果需要保留,可以放在cookie
中
📕 HTTP Cookie
和 Session
都是用于在 Web 应用中跟踪用户状态的机制。 Cookie 是存储在客户端的, 而 Session 是存储在服务器端的。 它们各有优缺点, 通常在实际应用中会结合使用, 以达到最佳的用户体验和安全性。