深入理解HTTP Cookie

🍑个人主页:Jupiter.
🚀 所属专栏:Linux从入门到进阶
欢迎大家点赞收藏评论😊

在这里插入图片描述

在这里插入图片描述

目录

    • ` HTTP Cookie`
      • `定义`
      • `工作原理`
      • `分类`
      • `安全性`
      • `用途`
    • `认识 cookie`
      • `基本格式`
      • `实验测试 cookie`


当我们登录了B站过后,为什么下次访问B站就不需要登陆了?

  • 问题:B 站是如何认识我这个登录用户的?
  • 问题:HTTP 是无状态,无连接的,怎么能够记住我?

HTTP Cookie

定义

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

工作原理

  • 当用户第一次访问网站时,服务器会在响应的 HTTP 头中设置 Set-Cookie字段(如Set-Cookie : user = zhangsan),用于发送 Cookie 到用户的浏览器。
  • 浏览器在接收到 Cookie 后,会将其保存在本地(通常是按照域名进行存储)。
  • 在之后的请求中,浏览器会自动在 HTTP 请求头中携带 Cookie 字段,将之前保存的 Cookie 信息发送给服务器。

分类

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

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

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

  • 类似于下面这种方式:

安全性

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

用途

  • 用户认证和会话管理(最重要)
  • 跟踪用户行为
  • 缓存用户偏好等
  • 比如在 chrome 浏览器下,可以直接访问:link

认识 cookie

  • HTTP 存在一个报头选项:Set-Cookie, 可以用来进行给浏览器设置 Cookie值。
  • HTTP 响应报头中添加,客户端(如浏览器)获取并自行设置并保存Cookie。

服务器发送Cookie

  • 当客户端(如浏览器)首次请求服务器资源时,服务器可能会在HTTP响应中包含一个或多个Set-Cookie头部。这些Set-Cookie头部指示客户端存储特定的信息(即Cookie)。
  • 每个Set-Cookie头部都包含了Cookie的名称、值以及可选的属性,如过期时间(Expires/Max-Age)、作用域(Path)、安全性要求(Secure)、跨站策略(SameSite)以及是否只能通过HTTP接口访问(HttpOnly)等。

客户端接收并保存Cookie

  • 浏览器接收到包含Set-Cookie头部的HTTP响应后,会解析这些头部,并根据其中的指令将Cookie存储到本地。
  • 存储的Cookie会包含名称、值以及所有相关的属性。
  • 浏览器会根据Cookie的过期时间和其他属性来决定何时删除这些Cookie。

客户端发送Cookie

  • 当浏览器再次向同一服务器(或符合Cookie作用域的其他服务器)发送请求时,它会自动检查是否有与该请求相关的Cookie。如果有,浏览器会将这些Cookie附加到HTTP请求的Cookie头部,并发送给服务器。服务器接收到请求后,可以从Cookie头部中读取这些Cookie,并根据需要处理它们。

基本格式

在这里插入图片描述
完整的 Set-Cookie 示例
在这里插入图片描述
时间格式必须遵守 RFC 1123 标准,具体格式样例:Tue, 01 Jan 2030 12:34:56 GMT 或者 UTC(推荐)。
关于时间解释

  • Tue: 星期二(星期几的缩写)
  • , : 逗号分隔符
  • 18: 日期(两位数表示)
  • Thu: 月份的缩写
  • 2024: 年份(四位数)
  • 12:34:56: 时间(小时、分钟、秒)
  • GMT: 格林威治标准时间(时区缩写)

GMT 和 UTC 都曾是或现在是国际上重要的时间标准,但由于地球自转的不规则性和原子钟的精确性,UTC 已经成为了全球性的标准时间,而 GMT 则更多被用作历史和地理上的参考。

关于其他可选属性的解释

  • expires=<date>:设置 Cookie 的过期日期/时间。如果未指定此属性,则 Cookie 默认为会话 Cookie,即当浏览器关闭时过期。
  • path=<some_path>:限制 Cookie 发送到服务器的哪些路径。默认为设置它的路径。
  • domain=<domain_name>:指定哪些主机可以接受该 Cookie。默认为设置它的主机。
  • secure:仅当使用 HTTPS 协议时才发送 Cookie。这有助于防止Cookie 在不安全的 HTTP 连接中被截获。
  • HttpOnly:标记 Cookie 为 HttpOnly,意味着该 Cookie 不能被客户端脚本(如 JavaScript)访问。这有助于防止跨站脚本攻击(XSS)。

以下是对 Set-Cookie 头部字段的简洁介绍

注意事项

  • 每个 Cookie 属性都以分号(;)和空格( )分隔。
  • 名称和值之间使用等号(=)分隔。
  • 如果 Cookie 的名称或值包含特殊字符(如空格、分号、逗号等),则需要进行 URL 编码。

Cookie 的生命周期

  • 如果设置了 expires 属性,则 Cookie 将在指定的日期/时间后过期。
  • 如果没有设置 expires 属性,则 Cookie 默认为会话 Cookie,即当浏览器关闭时过期。

安全性考虑

  • 使用 secure 标志可以确保 Cookie 仅在 HTTPS 连接上发送,从而提高安全性。
  • 使用 HttpOnly 标志可以防止客户端脚本(如 JavaScript)访问 Cookie,从而防止 XSS 攻击。
  • 通过合理设置 Set-Cookie 的格式和属性,可以确保 Cookie 的安全性、有效性和可访问性,从而满足 Web 应用程序的需求。

实验测试 cookie

测试 cookie 的关键性完整代码全部附在最后。

  • 测试 cookie 写入到浏览器
    resp.AddHeader("Set-Cookie: username=zhangsan;"); //响应中添加一行报头即可
  • 测试自动提交
  • 测试写入过期时间
    • 这里要由我们自己形成 UTC 统一标准时间:
    //时间格式如: expires=Thu, 18 Dec 2024 12:00:00 UTCstd::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 UTCsnprintf(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;}

在这里插入图片描述

  • 测试路径 path

提交到非/a/b 路径下

  • 比如:http://8.137.19.140:8888/a/x
  • 比如:http://8.137.19.140:8888/
  • 比如:http://8.137.19.140:8888/x/y

在这里插入图片描述
单独使用 Cookie,有什么问题?

  • 我们写入的是测试数据,如果写入的是用户的私密数据呢?比如,用户名密码,浏览痕迹等。
  • 本质问题在于这些用户私密数据在浏览器(用户端)保存,非常容易被人盗取,更重要的是,除了被盗取,还有就是用户私密数据也就泄漏了。

Cookie测试代码

#pragma once#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <memory>
#include <ctime>
#include "TcpServer.hpp"const std::string HttpSep = "\r\n";// 可以配置的
const std::string homepage = "index.html";
const std::string wwwroot = "./wwwroot";class HttpRequest
{
public:HttpRequest() : _req_blank(HttpSep), _path(wwwroot){ }bool GetLine(std::string &str, std::string *line){auto pos = str.find(HttpSep);if (pos == std::string::npos)return false;*line = str.substr(0, pos); // \r\nstr.erase(0, pos + HttpSep.size());return true;}bool Deserialize(std::string &request){std::string line;bool ok = GetLine(request, &line);if (!ok)return false;_req_line = line;while (true){bool ok = GetLine(request, &line);if (ok && line.empty()){_req_content = request;break;}else if (ok && !line.empty()){_req_header.push_back(line);}else{break;}}return true;}~HttpRequest(){}
private:// http报文自动std::string _req_line; // method url http_versionstd::vector<std::string> _req_header;std::string _req_blank;std::string _req_content;// 解析之后的内容std::string _method;std::string _url; //    /dira/dirb/x.html   /dira/dirb/XX?usrname=100&&password=1234 /dira/dirbstd::string _http_version;std::string _path;   // "./wwwroot"std::string _suffix; // 请求资源的后缀
};const std::string BlankSep = " ";
const std::string LineSep = "\r\n";class HttpResponse
{
public:HttpResponse() : _http_version("HTTP/1.0"), _status_code(200), _status_code_desc("OK"), _resp_blank(LineSep){}void SetCode(int code){_status_code = code;}void SetDesc(const std::string &desc){_status_code_desc = desc;}void MakeStatusLine(){_status_line = _http_version + BlankSep + std::to_string(_status_code) + BlankSep + _status_code_desc + LineSep;}void AddHeader(const std::string &header){_resp_header.push_back(header+LineSep);}void AddContent(const std::string &content){_resp_content = content;}std::string Serialize(){MakeStatusLine();std::string response_str = _status_line;for (auto &header : _resp_header){response_str += header;}response_str += _resp_blank;response_str += _resp_content;return response_str;}~HttpResponse() {}
private:std::string _status_line;std::vector<std::string> _resp_header;std::string _resp_blank;std::string _resp_content; // body// httpversion StatusCode StatusCodeDescstd::string _http_version;int _status_code;std::string _status_code_desc;
};class Http
{
private: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 UTCsnprintf(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;}
public:Http(uint16_t port){_tsvr = std::make_unique<TcpServer>(port, std::bind(&Http::HandlerHttp, this, std::placeholders::_1));_tsvr->Init();}std::string ProveCookieWrite() // 证明cookie能被写入浏览器{return "Set-Cookie: username=zhangsan;";}// resp.AddHeader(ProveCookieWrite()); //测试cookie被写入与自动提交std::string ProveCookieTimeOut(){return "Set-Cookie: username=zhangsan; expires=" + ExpireTimeUseRfc1123(60) + ";"; // 让cookie 1min后过期}std::string ProvePath(){return "Set-Cookie: username=zhangsan; path=/a/b;";}std::string ProveOtherCookie(){return "Set-Cookie: passwd=1234567890; path=/a/b;";}std::string HandlerHttp(std::string request){HttpRequest req;req.Deserialize(request);req.DebugHttp();lg.LogMessage(Debug, "%s\n", ExpireTimeUseRfc1123(60).c_str());HttpResponse resp;resp.SetCode(200);resp.SetDesc("OK");resp.AddHeader("Content-Type: text/html");// resp.AddHeader(ProveCookieWrite()); //测试cookie被写入与自动提交// resp.AddHeader(ProveCookieTimeOut()); //测试过期时间的写入// resp.AddHeader(ProvePath()); // 测试路径resp.AddHeader(ProvePath());resp.AddHeader(ProveOtherCookie());resp.AddContent("<html><h1>helloworld</h1></html>");return resp.Serialize();}void Run(){_tsvr->Start();}~Http(){}
private:std::unique_ptr<TcpServer> _tsvr;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/443584.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript 变量的简单学习

目录 1. 变量 1.1 变量是什么 1.2 变量基本使用 1.2.1 声明变量 1.2.2 变量赋值 1.2.3 变量更新 1.2.4 声明多个变量 1.3 变量案例 1.3.1 弹出姓名 1.3.2 交换变量的值 1.4 变量的本质 1.5 变量命名规则 1.6 var VS let 1. 变量 1.1 变量是什么 1.2 变量基本使用 …

Lazada菲律宾本土店选品怎么操作?EasyBoss ERP选品功能来帮你!

由于Lazada本土店在流量、履约速度、类目限制以及回款速度方面的优势&#xff0c;越来越多的Lazada卖家都在考虑转型做本土店&#xff0c;但本土化落地并不是一件容易的事&#xff0c;很多卖家在选品阶段就踩大坑了。 因此&#xff0c;为了选品不踩坑&#xff0c;很多卖家都会…

天海一体,遨游双卫星智能终端扬帆5G智慧海洋

海洋面积占地球表面的70%以上&#xff0c;世界贸易的90%左右由国际海运行业承运。但是&#xff0c;信号覆盖不均、通信延迟高、定位精度不足等问题&#xff0c;严重制约了海洋作业的效率与安全。智慧海洋&#xff0c;通信先行&#xff0c;AORO M5-5G双卫星智能终端应时代需求而…

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习06(Docker网络连接)

如果要搭建基于docker的私人DC&#xff0c;除了虚拟机网络连接外&#xff0c;就得掌握docker的网络连接。磨刀不误砍柴工&#xff0c;或者说工欲善其事必先利其器&#xff0c;我们先学学典型的docker的网络连接方式。Docker的网络连接有四种&#xff1a;bridge、none、containe…

【10086网上营业厅-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【小沐学CAD】ParaView Web的学习笔记(Python)

文章目录 1、简介1.1 visualizer1.2 Divvy1.3 Lite1.4 LightViz1.5 ArcticViewer1.6 HPCCloud1.7 glance1.8 trame 结语 1、简介 https://pvw.kitware.com/ VTK/ParaView Web&#xff0c;用于 Web 数据处理和可视化的框架 ParaViewWeb 是一个 Web 框架&#xff0c;用于在 Web …

大数据-162 Apache Kylin 全量增量Cube的构建 Segment 超详细记录 多图

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Redis:分布式 - 哨兵

Redis&#xff1a;分布式 - 哨兵 概念哨兵 Docker 搭建哨兵分布式选举流程 概念 Redis 的主从复制模式下&#xff0c;一旦主节点由于故障不能提供服务&#xff0c;需要人工进行主从切换&#xff0c;同时大量的客户端需要被通知切换到新的主节点上&#xff0c;对于上了一定规模…

【LeetCode HOT 100】详细题解之回溯篇

【LeetCode HOT 100】详细题解之回溯篇 回溯法的理论基础回溯法解决的问题理解回溯法回溯法模板 46 全排列思路代码 78 子集思路代码 17 电话号码的字母组合思路代码 39 组合总和思路代码 22 括号生成思路代码 79 单词搜索思路代码 131 分割回文串思路代码 51 N皇后思路代码 回…

打造梦幻AI开发环境:一步步解锁高效配置的魅力

作者简介&#xff1a;我是团团儿&#xff0c;是一名专注于云计算领域的专业创作者&#xff0c;感谢大家的关注 座右铭&#xff1a; 云端筑梦&#xff0c;数据为翼&#xff0c;探索无限可能&#xff0c;引领云计算新纪元 个人主页&#xff1a;团儿.-CSDN博客 目录 前言&#…

疾病防控|基于springBoot的疾病防控综合系统设计与实现(附项目源码+论文+数据库)

私信或留言即免费送开题报告和任务书&#xff08;可指定任意题目&#xff09; 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何…

基于SpringBoot+Vue的农场管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

通过Fiddler抓包采集某音作品列表,视频列表

声明&#xff1a;文章仅用于学习交流,如有侵权请联系删除 今天分享下某音app作品列表采集方法&#xff0c;我只详细说一下大步骤&#xff0c;细节就不多说了&#xff0c;留着大家去试吧 我们通过Fiddler 快捷方式 配置好代理 打开抖音进行抓包&#xff0c;随便找个达人打开主…

计算机的错误计算(一百一十七)

摘要 算式“(5^25*(1/25)^(1/5)*3^25(1/25)^(1/5)*5^25*3^(251/5)-(9/25)^(1/5)*3^25*5^25-(1/25)^(1/5)*3^25*5.0^25*(13^(1/5)-3^(2/5.0)))” 的准确值是0. 但是&#xff0c;Python 与 Excel 均输出了错误结果&#xff1a;一个含有15位整数&#xff0c;一个含有14位整数。 …

stm32学习笔记-RTC实时时钟

文章目录 一、RTC基础知识1.1 RTC简介1.2 RTC的晶振 二、stm32的RTC2.1 RTC和后备寄存器2.2 stm32 RTC结构框图及特性 三、stm32 RTC编程2.1 RTC初始化2.2 RTC控制程序 一、RTC基础知识 1.1 RTC简介 实时时钟的缩写是RTC(Real_Time Clock)。RTC 是集成电路&#xff0c;通常称…

【机器学习】深度学习、强化学习和深度强化学习?

深度学习、强化学习和深度强化学习是机器学习的三个重要子领域。它们有着各自独特的应用场景和研究目标&#xff0c;虽然都属于机器学习的范畴&#xff0c;但各自的实现方式和侧重点有所不同。 1. 深度学习&#xff08;Deep Learning&#xff09; 深度学习是一种基于神经网络的…

76.【C语言】perror函数介绍

1.cplusplus的官网介绍 cplusplus的介绍 点我跳转 2.翻译 函数 perror void perror ( const char * str ); 打印错误信息 将errno(最后一个错误数字)的值解释为错误信息,之后把它打印到stderr中(标准错误输出流,通常是控制台)(备注有关"流"的概念在75.【C语言】文件…

CMake 属性之目录属性

【写在前面】 CMake 的目录属性是指在特定目录&#xff08;及其子目录&#xff09;范围内有效的设置。 这些属性不同于全局变量或目标&#xff08;Target&#xff09;属性&#xff0c;它们提供了一种机制&#xff0c;允许开发者为项目中的不同部分定义不同的构建行为。 通过目录…

Jax(Random、Numpy)常用函数

目录 Jax vmap Array reshape Random PRNGKey uniform normal split choice Numpy expand_dims linspace jax.numpy.linalg[pkg] dot matmul arange interp tile reshape Jax jit jax.jit(fun, in_shardingsUnspecifiedValue, out_shardingsUnspecifiedVa…

docker compose一键部署容器监控 CAdvisor+InfluxDB+Granfana

docker compose一键部署容器监控 CAdvisorInfluxDBGranfana CAdvisor监控收集InfluxDB存储数据Granfana展示图表 1、原生命令 通过docker stats 命令可以查看当前宿主机上所有创建的容器的CPU,内存和网络流量等信息 docker stats 缺点&#xff1a;只能查看当前宿主机的全部…