【HTTP】Cookie 和 Session 详解

2023-09-20 16:47:39

一. Cookie

1. 什么是 Cookie

Cookie(中文意思为 “曲奇饼,小甜饼”): 我们这里指一种小型文本文件,通常由网站服务器发送到用户的浏览器,然后存储在用户的计算机上。用于跟踪、识别和存储关于用户在网站上的活动和偏好的信息。

Cookie 就是浏览器给页面提供的一种能持久化存储数据的机制。

  • 浏览器为了安全默认是不让网页访问用户电脑上的文件系统, 但是有时确实需要让页面存储一些数据,方便后续访问网站。
    于是浏览器不让页面访问整个磁盘数据,但是单独给页面分配了一块空间,有多种不同的形式, Cookie 是最经典的形式。

2. Cookie 的作用

服务器将 Cookie 返回给浏览器, 客户端(浏览器)这边就会通过 Cookie 保存当前用户的状态,当客户端访问服务器时,就会自动把 Cookie 内容带入到请求中,服务器接收到之后,就能知道当前客户是谁,现在客户端处于什么状态了,当前客户的服务提供到哪个环节了。Cookie 就像是 服务器在客户端搞的一个寄存处一样。

比如: 我们访问 抖音:

在这里插入图片描述

3. Cookie 的组成

  1. Key(名称)

  2. Value (值) : 根据 Key 可以获取对应的 value.

  3. Domain(域名): 指定可以访问 Cookie 的域名。通常情况下,Cookie 只能被设置在创建它的域名以及其子域名下。上图中我们访问的是 抖音, 那么 Cookie 的 Domain 就是 douyin.com。

  4. Path(路径): 指定可以访问 Cookie 的路径。这个字段定义了在哪些路径下的请求可以发送 Cookie。上图中 Path 为 “/”, 说明只要是 douyin.com 这个域名, 不管访问的是抖音 的哪个路径下的资源, 都可以在请求中使用浏览器中存储的 Cookie。

  5. Expires(过期时间): 一旦过了这个时间,浏览器将不再发送该 Cookie。如果未设置 Expires 字段,Cookie 将被视为会话 Cookie,它会在用户关闭浏览器时自动删除。

  6. 大小: 指定了 Cookie 的大小,单位为字节。

  7. HttpOnly: 布尔值字段,设置为 true,那么该 Cookie 只能通过 HTTP 或 HTTPS 协议访问,不能通过 JavaScript 或其他客户端脚本访问。有助于增强安全性,以防止恶意脚本访问敏感信息。

  8. Secure: 布尔值字段,设置为 true,那么该 Cookie 只能在通过 HTTPS 等安全连接发送时才会被浏览器发送到服务器。有助于保护敏感信息的传输安全。

  9. SameSite: 限制第三方cookie,表示Cookie不随着跨域请求发送,减少安全风险。它可以有三个可能的值:Strict、Lax、None。
    Strict 表示只有在同一站点的请求中才会发送 Cookie;
    Lax 在某些情况下允许 Cookie 在跨站点请求中发送(例如从外部链接打开的页面);
    None 允许 Cookie 在任何情况下都发送。
    SameSite 设置有助于减少跨站点请求伪造(CSRF)攻击和提高隐私。

  10. Partition Key(分区键): 一个标识符,指示 Cookie 属于哪个上下文或分区。它通常用于在浏览器中隔离不同网站或应用程序的 Cookie 数据,以增强隐私和安全性。每个不同的域名下都可以有不同的 Cookie, 不同网站之间的 Cookie 并不冲突.

  11. Priority(优先级): 指定了 Cookie 的传输优先级。Cookie数量超出限制时低优先级会被优先清除.

4. Cookie 的组织形式

  1. 先按照域名进行组织, 针对每个域名, 分别分配一块空间.
  2. 一块空间里又会按照键值对的方式组织数据.

5. Cookie 的传输

响应中: 服务器通过 Set-Cookie 字段返回 Cookie 给浏览器
此时 Cookie 中包含各个字段, 如 Domain, Path, HttpOnly 等, 这是服务器让浏览器知道什么时候才能使用这些 Cookie.

在这里插入图片描述

浏览器接收到 Cookie 后存储下来

在这里插入图片描述

再次发送请求时使用 Cookie 字段, 将 Cookie 发送给 服务器。

在这里插入图片描述

单看请求中的 Cookie 就是:
以键值对的形式, 只有 key 和 value, 没有其他字段, 其他字段只是辅助浏览器判断什么时候在请求中使用 Cookie 的.
在这里插入图片描述

服务器接收到包含 Cookie 的请求后,会解析 Cookie 并根据其中的信息执行相应的操作,例如,验证用户身份、提供个性化内容或记录用户活动等。

6. 如何提高 Cookie 的安全性

  1. 对 Cookie 中的信息加密.
  2. HttpOnly 设为 true, 那么该 Cookie 将只能通过 HTTP 或 HTTPS 协议访问,而不能通过 JavaScript 或其他客户端脚本访问, 防止其他恶意脚本访问 Cookie 盗取信息.
  3. Secure 设为 true, 只通过 HTTPS 等安全连接发送时才会被浏览器发送到服务器, 防止其他恶意网站窃取 Cookie 信息.
  4. 设置 Cookie 过期时间.
  5. 给 Cookie 设置 IP 戳和 时间 戳, 设置 Cookie 在同个 IP 下多长时间失效.

注意: 上面这些设置都是服务器设置的, 因为 Cookie 本身就是 服务器返回给浏览器, 浏览器只是简单的进行了存储.

7. Cookie 类

构造方法:

public Cookie(String name, String value)name 表示 Cookie 的名称, value 就是对应的值

普通方法:

方法名说明
String getName()该方法返回 cookie 的名称
String getValue()获取 cookie 的值
void setValue(String newValue)设置 cookie 的值
void setHttpOnly(boolean isHttpOnly)设置 HttpOnly 的值
void setSecure(boolean flag)设置 Secure 的值
void setDomain(String domain)设置可以访问 Cookie 的域名

Cookie 有一系列对应的 get 和 set 方法.

通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对.

        // 创建一个名为 "username" 的Cookie,并设置它的值为 "zhangsan"
        Cookie cookie = new Cookie("username", "zhangsan");
        // 设置Cookie的过期时间为1小时(以秒为单位)
        cookie.setMaxAge(3600); // 3600秒 = 1小时
        // 设置Cookie的路径,表示只有在指定路径下的请求才会发送该Cookie
        cookie.setPath("/example");
        // 设置Cookie的域名,表示只有在指定域名下的请求才会发送该Cookie
        cookie.setDomain(".example.com");
        // 设置Cookie为安全Cookie,只能在HTTPS连接下传输
        cookie.setSecure(true);
        // 设置HttpOnly属性,防止通过JavaScript访问Cookie
        cookie.setHttpOnly(true);
        // 将Cookie添加到HTTP响应中,以便将其发送到客户端
        response.addCookie(cookie); // response 是 HttpServletResponse 的实例

通过 HttpServletRequest.getCookies() 获取到请求中的一系列 Cookie 键值对.

        Cookie[] cookies = request.getCookies(); // request 是 HttpServletRequest 实例

Cookie 最重要的应用场景就是存储 会话 ID(SessionId), 进一步访问服务器后续页面时,能带上这个 id 从而让服务器知道当前用户信息。

二. Session

HTTP 协议自身是属于 “无状态” 协议.

“无状态” 的含义指的是:

  • 默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系.

但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了。

在这里插入图片描述

上面的令牌通常就是服务器以 Cookie 形式返回给浏览器, 服务器存储的用户信息对应的就是 Session。通常情况下,一个用户关联一个 Session (会话)。

举个栗子: 这个过程和去医院看病很相似.

  1. 到了医院先挂号. 挂号时需提供身份证, 同时得到了一张 “就诊卡”, 这个就诊卡就相当于患者的 “令牌”. 同时医院的系统中会记录用户的看病信息。
  2. 后续去各个科室进行检查, 诊断, 开药等操作, 都不必再出示身份证了, 只要凭就诊卡即可识别出当前患者的身份,知道患者的病史。
  3. 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的身份和就诊卡的关联就销毁了. (类似于网站的注销操作)
  4. 又来看病, 可以办一张新的就诊卡, 此时就得到了一个新的 “令牌”。

就诊卡就是 Cookie, 但是 Cookie 存储的数据是有限的,且易丢失,关键信息都存储在服务器上,以 会话(Session)的形式。

服务器这边就需要记录令牌信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作.

1. 理解会话机制 (Session)

  • 服务器同一时刻收到的请求是很多的. 服务器需要清除的区分清楚每个请求是从属于哪个用户, 就需要在服务器这边记录每个用户令牌以及用户的信息的对应关系.

  • 在上面的例子中, 就诊卡就是一张 “令牌”. 要想让这个令牌能够生效, 就需要医院这边通过系统记录每个就诊卡和患者信息之间的关联关系.

会话的本质就是一个 “哈希表”, 存储了一些键值对结构. key 就是令牌的 ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计).

sessionId 是由服务器生成的一个 “唯一性字符串”, 又叫 token
在这里插入图片描述

  • 当用户登陆的时候, 服务器在 Session 中新增一个新记录, 并把 sessionId / token 返回给客户端. (例如通过 HTTP 响应中的 Set-Cookie 字段返回).
  • 客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId/ token. (例如通过 HTTP 请求中的 Cookie 字段带上).
  • 服务器收到请求之后, 根据请求中的 sessionId / token 在 Session 信息中获取到对应的用户信息, 再进行后续操作.

Servlet 的 Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失,用户注销 Session 也会丢失, 同时 Session 也有过期时间。(Session 的默认过期时间30分钟)

2. Sessoin 的组织形式

在这里插入图片描述

HttpSession 这个对象本质也是一个 “键值对” 结构,每个 HttpSession 有其唯一的 ID,同时又包含若干键值对,里面的 key 和 value 由程序员自己定义,允许程序员往 HttpSession 对象中存储任意的键值对数据,但是 key 必须是 String , value 可以任意。

HttpSession 的每个键值对又称为属性(Attribute).

3. HttpSession 类

  1. 获取/创建 Session

HttpServletRequest 类 中有 获取 Session 的方法

方法描述
HttpSession getSession()在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null

为什么根据 HttpServletRequest 类能获取到 Session ?

  • 因为 HttpServletRequest 是对用户请求的抽象, 所以 HttpServletRequest 中会有请求中的 Cookie 信息,
  • 其中非常重要的一个 Cookie 就是 sessionId, 根据这个 ID , 就能找到 (或者找不到)对应的 会话。
  • 没找到时,说明之前没有创建,或者说过期了,
    如果参数为 true, 就会创建会话,并在里面填写一些必要的信息并返回会话, 最终返回响应时,会将新建的 会话的 ID 通过 Set-Cookie 字段返回给浏览器。
    如果为参数为 false, 直接返回 null.

响应中返回的 sessoinId
在这里插入图片描述

图中的 ZTZiMGRkY2YtYjQzYi00MWM3LTlhZjUtNTNkZmVkN2Q0MzM0 便是 sessionId

在这里插入图片描述

浏览器收到 Cookie 后, 进行存储,再次发送请求时便携带着这个 sessionId, 从而服务器能识别出来用户信息。

  1. HttpSession 类中的相关方法
    一个 HttpSession 对象里面包含多个键值对. 我们可以往 HttpSession 中存任何我们需要的信息.
方法描述
Object getAttribute(String name)根据 name 获取 值,找不到返回 null.
void setAttribute(String name, Object value)添加键值对, 键为 name , 值为 value
boolean isNew()判定当前是否是新创建出的会话

创建会话并存入键值对:

        // request 是 HttpServletRequest 实例
        HttpSession session = request.getSession(true); // 参数为 true, 没有 session 就创建
        // 存入键值对
        session.setAttribute("username", "zhangsan");
        session.setAttribute("age", 18);
        session.setAttribute("password", "123456");

根据会话获取键值对:

        // request 是 HttpServletRequest 实例
        HttpSession session = request.getSession(false); // 参数为 false, 没有 session 返回 null, 通常用来验证用户是否已经登录时用
        // 获取键值对, 注意要转换类型, 因为 返回值类型是 Object
        String username = (String) session.getAttribute("username");
        int age = (int) session.getAttribute("username");
        String password = (String)session.getAttribute("password");

三. Cookie 和 Session 的联系与区别

联系:在网站的登录功能种,Cookie 与 Session 需要配合使用

区别:

  • Cookie 是客户端的机制. Session 是服务器端的机制.
  • Cookie 里面可以存储各种键值对(还可以存储别的),Session 专门用来保存用户的身份信息。
  • Cookie 和 Session 经常会在一起配合使用. 但是不是必须配合.
    完全可以用 Cookie 来保存一些数据在客户端. 这些数据不一定是用户身份信息, 也不一定是token / sessionId.
    Session 中的 token / sessionId 也不需要非得通过 Cookie / Set-Cookie 传递.比如使用 手机 APP 进行登录,服务器里面还需要 Session, 但是就没有 Cookie 这个概念。也就是说 Cookie 是与 浏览器强相关的。

好啦! 以上就是对 Cookie 和 Session 的讲解,希望能帮到你 !
评论区欢迎指正 !

更多推荐

Netty面试题(二)

文章目录前言一、Netty的线程模型?二、TCP粘包/拆包的原因及解决方法?三、了解哪几种序列化协议?总结前言Netty的线程模型?TCP粘包/拆包的原因及解决方法?了解哪几种序列化协议?一、Netty的线程模型?Netty通过Reactor模型基于多路复用器接收并处理用户请求,内部实现了两个线程池,boss线程池和w

合肥先进光源国家重大科技基础设施项目及配套工程启动会纪念

合肥先进光源国家重大科技基础设施项目及配套工程启动会纪念卡西莫多合肥长丰岗集里肥鸭从此别泥塘先平场地设围栏进而工地筑基忙光阴似箭指日争源流汇智山水长国器西北扩新地家校又添新区园重器托举有群力大步穿梭两地间科教兴邦大国策技术盈身坦荡行基坑从今开挖砌础柱继而深潜立设计蓝图逐展开施工巧匠刻惊奇项颈昂起躲绞索目光如炬细察析及时

数据库小记-mysql-DDL、DML、DQL

MySQL是一个流行的关系型数据库管理系统,支持各种数据库操作语言(DataManipulationLanguage,DML)、数据库定义语言(DataDefinitionLanguage,DDL)和数据查询语言(DataQueryLanguage,DQL)。以下是它们的主要区别和示例:DDL(数据定义语言):DDL用

【youcans动手学模型】目标检测之 SPPNet 模型

欢迎关注『youcans动手学模型』系列本专栏内容和资源同步到GitHub/youcans【youcans动手学模型】目标检测之SPPNet模型1.SPPNet卷积神经网络模型1.1论文摘要1.2技术背景1.3空间金字塔池化1.4目标检测1.5总结2.在PyTorch中定义SPP模型类2.1SPP层的参数计算2.2定义

AI实战营第二期 第五节 《目标检测与MMDetection》——笔记6

文章目录摘要主要特性常用概念框、边界框交并比(loU)感受野有效感受野置信度目标检测的基本思路难点滑框在特征图进行密集计算边界框回归基于锚框VS无锚框NMS(非极大值抑制)使周密集预测模型进行推理步骤如何训练密集预测模型的训练匹配的基本思路密集检测的基本范式多尺度预测如何处理尺度问题基于锶框(Anchor)图像金字塔I

【需求侧响应】综合能源中多种需求响应——弹性电价、可平移及可削减研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1概述📚2运行结果🎉3参考文献🌈4Matlab代码及数据💥1概述需求侧响应是一种通过调整能源消费行为以适应电网需

高比例清洁能源接入下计及需求响应的配电网重构(matlab代码)

1主要内容该程序复现《高比例清洁能源接入下计及需求响应的配电网重构》,以考虑网损成本、弃风弃光成本和开关操作惩罚成本的综合成本最小为目标,针对配电网重构模型的非凸性,引入中间变量并对其进行二阶锥松弛,构建混合整数凸规划模型,采用改进的IEEE33节点配电网进行算例仿真,分析了需求响应措施和清洁能源渗透率对配电网重构结果

基于yolov5的交通标志牌的目标检测研究——源码及文档

有需要本项目的全套代码和资源以及部署的可以私信博主!!!!!此外本项目所需的深度学习环境点击顶部即可下载,解压可以使用,直接跑所有的深度学习模型,超级方便!本课题研究,通过利用提供的公开数据集TT100K图标进行筛选和整理,最终得到TT100K数据中的45类交通标志牌数据。并将数据集进行分割,其中训练集:6664条;验

FFmpeg5.1.3编译动态库详细教程(基于Linux虚拟机)

FFmpeg编译详细教程FFmpeg编译详细教程本文原创:猿视野(一家分享技术架构思路,扩展程序员视野的网站,遇到技术问题,可以加联系方式相互交流)转载请注明出处和相关链接,否则追究其法律责任!原文地址:https://developer.aliyun.com/article/1326862?source=5176.1

【AI】机器学习——支持向量机(非线性及分析)

5.支持向量机(线性SVM)文章目录5.4非线性可分SVM5.4.1非线性可分问题处理思路核技巧核函数特点核函数作用于SVM5.4.2正定核函数由K(x,z)K(x,z)K(x,z)构造H\mathcal{H}H空间步骤常用核函数5.5SVM参数求解算法5.6SVM与线性模型关系5.4非线性可分SVM5.4.1非线性可

仿照Everything实现的文件搜索工具--SearchEverything

一、项目介绍项目名称:SearchEverything项目简介:SearchEverything是仿照Everything实现的一款桌面级的文件搜索软件,它是Everything的增强版,支持跨平台的使用。项目功能:1.选择文件夹后,多线程扫描文件夹下的子文件夹,显示文件的名称、路径、文件类型(文件夹还是文件)、文件大

热文推荐