Cookie与Session
目录
前言
一.Cookie
1.1Cookie是什么?
1.2怎么查看浏览器中缓存的Cookie?
1.3Cookie格式
1.4Cookie有什么问题?
二.Session
2.1Session是什么?
2.2Session存在的问题?
前言
当你劳累了一天回到家中,打开Bilibili刷一会视频,但是你发现B站一般会让我们进行登录操作,当我们登录完成之后,一段时间内都不需要我们重新进行登录;你有没有想过这是为什么,为什么我登录一次之后就不用重复登录了?Cookie就是帮助我们完成这个任务的【功臣】

一.Cookie
1.1 Cookie是什么?
Cookie在英文中有“饼干”、“点心”的意思。
Cookie是HTTP协议报头中的一个字段,用来携带用户的信息;当向相关的HTTP服务器第一次发送诸如【登录】这种需要对用户身份进行鉴别的请求的时候,HTTP服务器需要验证我们的身份,通常第一次登录操作,我们的身份信息是设置在Authorization字段中的,HTTP服务器收到携带身份信息的请求后,就会返回一个携带Cookie的响应头,只要我们使用这个响应头中的Cookie就可以在之后的登录中不用再进行身份的验证。我们的浏览器通常会将响应中的Cookie信息自动的进行保存并在发起请求时,自动将Cookie信息填写到我们的请求头中,而不需要我们进行手动的设置。
1.2 怎么查看浏览器中缓存的Cookie?
使用联想自带的浏览器进行验证,实际上浏览器的UI大体相差不大,我用Google浏览器看了一下也是这个UI,所以你也可以使用Google浏览器进行验证。

1.3 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
属性 | 值 | 描述 |
username | username | 这是 Cookie 的名称和值,标识用户名为"peter"。 |
expires | Thu, 18 Dec 2024 12:00:00 UTC | 指定Cookie的过期时间。 在这个例子中, Cookie将在 2024 年 12 月 18 日 12:00:00 UTC 后过期。 |
path | / | 定义Cookie的作用范围。 这里设置为根路径/,意味着 Cookie 对.example.com域名下的所有路径 都可用。 |
domain | .example.com | 指定哪些域名可以接收这个Cookie。 点前缀(.) 表示包括所有 子域名。 |
secure | - | 指示Cookie只能通过HTTPS协议发送, 不能通过HTTP协议发送,增加安全性。 |
HttpOnly | - | 阻止客户端脚本(如 JavaScript)访问此 Cookie,有助于防止跨站脚本攻击(XSS) 。 |
我们写一个简单的HTTP服务器,来验证一下Cookie的存在。并尝试一下向Cookie写入一些限制字段。
HTTP服务端代码:
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ctime>#define PORT 8080
#define BUFFER_SIZE 1024void handle_client(int client_socket) {char buffer[BUFFER_SIZE] = {0};read(client_socket, buffer, BUFFER_SIZE);// 生成一个简单的 Cookiestd::time_t now = std::time(nullptr);std::string cookie_value = "value_" + std::to_string(now);std::string cookie_header = "Set-Cookie: my_cookie=" + cookie_value + "; Path=/\r\n";std::string response = "HTTP/1.1 200 OK\r\n";response += cookie_header;response += "Content-Type: text/html\r\n";response += "\r\n";response += "<html><body><h1>Hello! You've received a cookie.</h1></body></html>";send(client_socket, response.c_str(), response.length(), 0);close(client_socket);
}int main() {int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);// 创建套接字if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 设置套接字选项if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定套接字到指定地址和端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 监听连接if (listen(server_fd, 3) < 0) {perror("listen");exit(EXIT_FAILURE);}std::cout << "Server listening on port " << PORT << std::endl;while (true) {if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");continue;}handle_client(new_socket);}close(server_fd);return 0;
}
编译:
g++ http_server_with_cookie.cpp -o http_server

1.4 Cookie有什么问题?
在图3中,我们可以清晰地看到服务端返回的Cookie信息都是未被加密的,这就导致了如果我们的Cookie信息泄漏了,就可能会造成用户个人隐私的或关键信息的泄漏进而给用户造成损失。
在图3所对应的示例中你可能感觉并不明显。但是如果Cookie中的信息包含你登录某个网站时的账号密码信息,那么你的账号和密码很容易就会泄漏。,你的账号密码泄漏之后,别人就可以以你的身份进行一些非法操作。
综上所述,Cookie主要存在两个问题:信息未加密、身份被冒用。
二.Session
2.1 Session是什么?
刚才我们也提到了,服务器会将我们用户的信息明文式的写入到Cookie中,那么在服务端,我们将用户的信息与一个唯一ID相绑定,并将这个ID设置进Cookie中就可以解决了明文Cookie的信息泄漏问题。服务器生成ID并使用ID进行用户会话跟踪的这种机制就叫做Session。
2.2 Session存在的问题?
尽管Session机制解决了,Cookie中存在用户敏感信息这一问题,但是没有解决用户身份被冒用的问题,在一些情况下单一的Session机制,有心之人仍然可能冒用用户的身份进行不法操作,但是现在也存在一些相应的辅助手段来让身份冒用变得更加复杂。
比如,我们可以定期更新Session ID,使之在合理时间范围内使用。也可以设置多重身份验证。但是,百密总有一疏的时候,要想不泄露自己的身份信息,合法合规安全上网不给不法分子可乘之机才是解决问题的根本。