【2023】cookie是什么?有什么用?一篇文章彻底搞懂cookie

一个不大不小的问题

假设服务器有一个接口,通过请求这个接口,可以添加一个管理员

但是,不是任何人都有权力做这种操作的

那么服务器如何知道请求接口的人是有权力的呢?

答案是:只有登录过的管理员才能做这种操作

可问题是,客户端和服务器的传输使用的是http协议,http协议是无状态的,什么叫无状态,就是服务器不知道这一次请求的人,跟之前登录请求成功的人是不是同一个人

img

img

由于http协议的无状态,服务器忘记了之前的所有请求,它无法确定这一次请求的客户端,就是之前登录成功的那个客户端。

你可以把服务器想象成有着严重脸盲症的东哥,他没有办法分清楚跟他说话的人之前做过什么

于是,服务器想了一个办法

它按照下面的流程来认证客户端的身份

  1. 客户端登录成功后,服务器会给客户端一个出入证
  2. 后续客户端的每次请求,都必须要附带这个出入证

img

服务器发扬了认证不认人的优良传统,就可以很轻松的识别身份了。

但是,用户不可能只在一个网站登录,于是客户端会收到来自各个网站的出入证,因此,就要求客户端要有一个类似于卡包的东西,能够具备下面的功能:

  1. 能够存放多个出入证。这些出入证来自不同的网站,也可能是一个网站有多个出入证,分别用于出入不同的地方
  2. 能够自动出示出入证。客户端在访问不同的网站时,能够自动的把对应的出入证附带请求发送出去。
  3. 正确的出示出入证。客户端不能将肯德基的出入证发送给麦当劳。
  4. 管理出入证的有效期。客户端要能够自动的发现那些已经过期的出入证,并把它从卡包内移除。

能够满足上面所有要求的,就是cookie

cookie类似于一个卡包,专门用于存放各种出入证,并有着一套机制来自动管理这些证件。

卡包内的每一张卡片,称之为一个cookie

cookie的组成

cookie是浏览器中特有的一个概念,它就像浏览器的专属卡包,管理着各个网站的身份信息。

每个cookie就相当于是属于某个网站的一个卡片,它记录了下面的信息:

  • key:键,比如「身份编号」
  • value:值,比如小王的身份编号「14563D1550F2F76D69ECBF4DD54ABC95」,这有点像卡片的条形码,当然,它可以是任何信息
  • domain:域,表达这个cookie是属于哪个网站的,比如hao.tech,表示这个cookie是属于hao.tech这个网站的
  • path:路径,表达这个cookie是属于该网站的哪个基路径的,就好比是同一家公司不同部门会颁发不同的出入证。比如/news,表示这个cookie属于/news这个路径的。(后续详细解释)
  • secure:是否使用安全传输(后续详细解释)
  • expire:过期时间,表示该cookie在什么时候过期

当浏览器向服务器发送一个请求的时候,它会瞄一眼自己的卡包,看看哪些卡片适合附带捎给服务器

如果一个cookie同时满足以下条件,则这个cookie会被附带到请求中

  • cookie没有过期
  • cookie中的域和这次请求的域是匹配的
    • 比如cookie中的域是hao.tech,则可以匹配的请求域是hao.techwww.hao.techblogs.hao.tech等等
    • 比如cookie中的域是www.hao.tech,则只能匹配www.hao.tech这样的请求域
    • cookie是不在乎端口的,只要域匹配即可
  • cookie中的path和这次请求的path是匹配的
    • 比如cookie中的path是/news,则可以匹配的请求路径可以是/news/news/detail/news/a/b/c等等,但不能匹配/blogs
    • 如果cookie的path是/,可以想象,能够匹配所有的路径
  • 验证cookie的安全传输
    • 如果cookie的secure属性是true,则请求协议必须是https,否则不会发送该cookie
    • 如果cookie的secure属性是false,则请求协议可以是http,也可以是https

如果一个cookie满足了上述的所有条件,则浏览器会把它自动加入到这次请求中

具体加入的方式是,浏览器会将符合条件的cookie,自动放置到请求头中,例如,当我在浏览器中访问百度的时候,它在请求头中附带了下面的cookie:

img

看到打马赛克的地方了吗?这部分就是通过请求头cookie发送到服务器的,它的格式是键=值; 键=值; 键=值; ...,每一个键值对就是一个符合条件的cookie。

**cookie中包含了重要的身份信息,永远不要把你的cookie泄露给别人!!!**否则,他人就拿到了你的证件,有了证件,就具备了为所欲为的可能性。

如何设置cookie

由于cookie是保存在浏览器端的,同时,很多证件又是服务器颁发的

所以,cookie的设置有两种模式:

  • 服务器响应:这种模式是非常普遍的,当服务器决定给客户端颁发一个证件时,它会在响应的消息中包含cookie,浏览器会自动的把cookie保存到卡包中
  • 客户端自行设置:这种模式少见一些,不过也有可能会发生,比如用户关闭了某个广告,并选择了「以后不要再弹出」,此时就可以把这种小信息直接通过浏览器的JS代码保存到cookie中。后续请求服务器时,服务器会看到客户端不想要再次弹出广告的cookie,于是就不会再发送广告过来了。

服务器端设置cookie

服务器可以通过设置响应头,来告诉浏览器应该如何设置cookie

响应头按照下面的格式设置:

set-cookie: cookie1
set-cookie: cookie2
set-cookie: cookie3
...

通过这种模式,就可以在一次响应中设置多个cookie了,具体设置多少个cookie,设置什么cookie,根据你的需要自行处理

其中,每个cookie的格式如下:

键=值; path=?; domain=?; expire=?; max-age=?; secure; httponly

每个cookie除了键值对是必须要设置的,其他的属性都是可选的,并且顺序不限

当这样的响应头到达客户端后,浏览器会自动的将cookie保存到卡包中,如果卡包中已经存在一模一样的卡片(其他path、domain相同),则会自动的覆盖之前的设置

下面,依次说明每个属性值:

  • path:设置cookie的路径。如果不设置,浏览器会将其自动设置为当前请求的路径。比如,浏览器请求的地址是/login,服务器响应了一个set-cookie: a=1,浏览器会将该cookie的path设置为请求的路径/login

  • domain:设置cookie的域。如果不设置,浏览器会自动将其设置为当前的请求域,比如,浏览器请求的地址是

    http://www.yuanjin.tech
    

    ,服务器响应了一个

    set-cookie: a=1
    

    ,浏览器会将该cookie的domain设置为请求的域

    www.yuanjin.tech
    
    • 这里值得注意的是,如果服务器响应了一个无效的域,浏览器是不认的
    • 什么是无效的域?就是响应的域连根域都不一样。比如,浏览器请求的域是yuanjin.tech,服务器响应的cookie是set-cookie: a=1; domain=baidu.com,这样的域浏览器是不认的。
    • 如果浏览器连这样的情况都允许,就意味着张三的服务器,有权利给用户一个cookie,用于访问李四的服务器,这会造成很多安全性的问题
  • expire:设置cookie的过期时间。这里必须是一个有效的GMT时间,即格林威治标准时间字符串,比如Fri, 17 Apr 2020 09:35:59 GMT,表示格林威治时间的2020-04-17 09:35:59,即北京时间的2020-04-17 17:35:59。当客户端的时间达到这个时间点后,会自动销毁该cookie。

  • max-age:设置cookie的相对有效期。expire和max-age通常仅设置一个即可。比如设置max-age1000,浏览器在添加cookie时,会自动设置它的expire为当前时间加上1000秒,作为过期时间。

    • 如果不设置expire,又没有设置max-age,则表示会话结束后过期。
    • 对于大部分浏览器而言,关闭所有浏览器窗口意味着会话结束。
  • secure:设置cookie是否是安全连接。如果设置了该值,则表示该cookie后续只能随着https请求发送。如果不设置,则表示该cookie会随着所有请求发送。

  • httponly:设置cookie是否仅能用于传输。如果设置了该值,表示该cookie仅能用于传输,而不允许在客户端通过JS获取,这对防止跨站脚本攻击(XSS)会很有用。

    • 关于如何通过JS获取,后续会讲解
  • 关于什么是XSS,不在本文讨论范围

下面来一个例子,客户端通过post请求服务器http://yuanjin.tech/login,并在消息体中给予了账号和密码,服务器验证登录成功后,在响应头中加入了以下内容:

set-cookie: token=123456; path=/; max-age=3600; httponly

当该响应到达浏览器后,浏览器会创建下面的cookie:

key: token
value: 123456
domain: yuanjin.tech
path: /
expire: 2020-04-17 18:55:00 #假设当前时间是2020-04-17 17:55:00
secure: false  #任何请求都可以附带这个cookie,只要满足其他要求
httponly: true #不允许JS获取该cookie

于是,随着浏览器后续对服务器的请求,只要满足要求,这个cookie就会被附带到请求头中传给服务器:

cookie: token=123456; 其他cookie...

现在,还剩下最后一个问题,就是如何删除浏览器的一个cookie呢?

如果要删除浏览器的cookie,只需要让服务器响应一个同样的域、同样的路径、同样的key,只是时间过期的cookie即可

所以,删除cookie其实就是修改cookie

下面的响应会让浏览器删除token

set-cookie: token=; domain=yuanjin.tech; path=/; max-age=-1

浏览器按照要求修改了cookie后,会发现cookie已经过期,于是自然就会删除了。

无论是修改还是删除,都要注意cookie的域和路径,因为完全可能存在域或路径不同,但key相同的cookie

因此无法仅通过key确定是哪一个cookie

客户端设置cookie

既然cookie是存放在浏览器端的,所以浏览器向JS公开了接口,让其可以设置cookie

document.cookie = "键=值; path=?; domain=?; expire=?; max-age=?; secure";

可以看出,在客户端设置cookie,和服务器设置cookie的格式一样,只是有下面的不同

  • 没有httponly。因为httponly本来就是为了限制在客户端访问的,既然你是在客户端配置,自然失去了限制的意义。
  • path的默认值。在服务器端设置cookie时,如果没有写path,使用的是请求的path。而在客户端设置cookie时,也许根本没有请求发生。因此,path在客户端设置时的默认值是当前网页的path
  • domain的默认值。和path同理,客户端设置时的默认值是当前网页的domain
  • 其他:一样
  • 删除cookie:和服务器也一样,修改cookie的过期时间即可

总结

以上,就是cookie原理部分的内容。

如果把它用于登录场景,就是如下的流程:

登录请求

  1. 浏览器发送请求到服务器,附带账号密码
  2. 服务器验证账号密码是否正确,如果不正确,响应错误,如果正确,在响应头中设置cookie,附带登录认证信息(至于登录认证信息是设么样的,如何设计,要考虑哪些问题,就是另一个话题了,可以百度 jwt)
  3. 客户端收到cookie,浏览器自动记录下来

后续请求

  1. 浏览器发送请求到服务器,希望添加一个管理员,并将cookie自动附带到请求中
  2. 服务器先获取cookie,验证cookie中的信息是否正确,如果不正确,不予以操作,如果正确,完成正常的业务流程

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud之OpenFeign介绍案例+相关面试题

概述 OpenFeign是一个声明式的WEB服务客户端,它使WEB服务客户端变得更加容易。具有可插拔的注解支持,SpringCloud中添加了SpringMVC注解的支持。SpringCloud中集成了Ribbon和Eureka,以及SpringCloud LoadBalance,以便在使用Feign时…

pyest+appium实现APP自动化测试,思路全总结在这里

目录 01、appium环境搭建 2、搭建pythonpytestappium环境 3、安装pycharm搭建项目编写脚本 4、执行测试 绵薄之力 01、appium环境搭建 安装nodejs http://nodejs.cn/ 为什么要安装nodejs? 因为appium这个工具的服务端是由nodejs语言开发的 安装jdk&#xf…

mysql数据库简介

1.什么是数据库:数据仓库。访问必须只能用SQL语句来访问。数据库也是一个文件的系统。 2.数据库的作用:存储数据的作用。开发任何的应用,都有数据库。 3.关系型的数据库:数据库中保存的都是实体与实体之间的关系。 4.常见的数据库…

2023接口自动化测试,完整入门篇

1. 什么是接口测试 顾名思义,接口测试是对系统或组件之间的接口进行测试,主要是校验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型,测试类型又主…

stata绘图指令

stata绘图指令 – 潘登同学的stata笔记 文章目录 stata绘图指令 -- 潘登同学的stata笔记 绘图概览韦恩图折线图连线图线性拟合图直方图 函数图添加特殊字符和文字 绘图概览 Stata 提供的图形种类: twoway 二维图scatter 散点图line 折线图area 区域图lfit 线性拟合…

基于单片机的温室大棚环境监测系统设计

温室大棚对北方反季节蔬菜的种植具有重要意义。据了解全国各地温室大棚使用集中,但是大棚环境调控方式落后、管理落后、生产效率比较低。针对此问题本文提出了一种基于STM32单片机智能温室大棚控制系统方案,实现环境参数的自动检测,以达到智能…

2023年股票代持行业研究报告

第一章 股票代持概述 1.1 基本概念 股票代持,或称委托持股,是指实际出资人与名义出资人达成以下约定:名义出资人作为名义股东,在股东名册等公司工商登记信息上出现,而实际上由实际出资人出资并享有投资权益。 股票代…

Segment Anything论文详解(SAM)

论文名称:Segment Anything 论文地址:https://arxiv.org/abs/2304.02643 开源地址:https://github.com/facebookresearch/segment-anything demo地址:Segment Anything | Meta AI 主要贡献:开发一个可提示的图像分…

图片存储方案-七牛云存储

1.引语 在实际开发中,我们会有很多处理不同功能的服务器。例如: 应用服务器:负责部署我们的应用 数据库服务器:运行我们的数据库 文件服务器:负责存储用户上传文件的服务器 分服务器处理的目的是让服务器各司其职…

设计模式简述

设计模式(简述) 设计模式的分类 ​ 根据目的可以分为创建型、结构性和行为型三类: 创建型模型:创建对象结构性模型:处理类或对象的组合行为型模式:用于描述对类或对象怎样交互和怎么分派职责 ​ 根据范围可以分为类模式和对象…

nvm-windows的安装使用及踩坑指南

nvm是node的一款版本管理工具,可以简单操作node版本的切换、安装、查看。常规来说,开发中安装一个node版本就够了,但是最近在开发中有的老项目或者一些特定的项目需要来回切换node的版本,不可能手动去卸载掉之前的node版本&#x…

013:Mapbox GL添加marker

第013个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中添加marker。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共70行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:https://xiaozhu…

算法时间复杂度计算

目录 1.时间复杂度计算 1.1 时间复杂度例题 1.1.1例题 1.1.2例题 1.1.3例题 1.1.4例题 1.2时间复杂度leetcode例题 1.时间复杂度计算 首先,我们需要了解时间复杂度是什么:算法的时间复杂度是指算法在编写成可执行程序后,运行时需要耗费…

使用 Floyd Warshall 检测负循环

我们得到了一个有向图。我们需要计算图形是否有负循环。负循环是循环的总和为负的循环。 在图形的各种应用中都可以找到负权重。例如,如果我们沿着这条路走,我们可能会得到一些好处,而不是为一条路付出代价。 例子:

Linux中的read/write和recv/send的区别,并使用recv/send实现简单的聊天功能

Linux中的read/write和recv/send的区别 r e a d / w r i t e read/write read/write的用法 r e c v / s e n d recv/send recv/send的用法 L i n u x Linux Linux中的 r e a d / w r i t e read/write read/write和 r e c v / s e n d recv/send recv/send的区别下面是一个使用…

Three.js教程:第一个3D场景

推荐:将 NSDT场景编辑器加入你3D工具链 其他工具系列: NSDT简石数字孪生 下面的代码完整展示了通过three.js引擎创建的一个三维场景,在场景中绘制并渲染了一个立方体的效果,为了大家更好的宏观了解three.js引擎, 尽量使…

基于SpringBoot的私人健身和教练的预约管理系统源码数据库论文

目 录 第一章 概述 1.1研究背景 1.2开发意义 1.3研究现状 1.4研究内容 1.5论文结构 第二章 开发技术介绍 2.1系统开发平台 2.2平台开发相关技术 2.2.1 Javar技术 2.2.2 Mysql数据库介绍 2.2.3 Mysql环境配置 2.2.4 B/S架构 2.2.5 Springboot框架 …

设计模式-结构型模式之外观模式

4. 外观模式 4.1. 模式定义 外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个 高层接口,这个接口使得这一子系统更加容易使用。外观模…

socket 到底是个啥

哈喽大家好,我是咸鱼 我相信大家在面试过程中或多或少都会被问到这样一个问题:你能解释一下什么是 socket 吗 我记得我当初的回答很是浅显:socket 也叫套接字,用来负责不同主机程序之间的网络通信连接,socket 的表现…

使用树状图可视化聚类

一般情况下,我们都是使用散点图进行聚类可视化,但是某些的聚类算法可视化时散点图并不理想,所以在这篇文章中,我们介绍如何使用树状图(Dendrograms)对我们的聚类结果进行可视化。 树状图 树状图是显示对象…
最新文章