Cookie 与 Session

目录

一、获取Cookie/Session

1、理解Cookie

2、理解Session

3、Cookie 和 Session 的区别

4、获取Cookie

4.1 传统获取Cookie

4.2 简洁获取Cookie

5、Session 存储和获取

5.1 Session存储

5.2 Session读取

5.3 简洁获取 Session


一、获取Cookie/Session

1、理解Cookie

HTTP 协议自身是属于 "无状态" 协议.
"无状态" 的含义指的是:
默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系.
但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了。

上述图中的 "令牌" 通常就存储在 Cookie 字段中

对于“令牌”,我们可以举一个医院的例子:

比如去医院挂号 :
  1. 看病之前先挂号. 挂号时候需要提供身份证号, 同时得到了⼀张 "就诊卡", 这个就诊卡就相当于患者的 "令牌".
  2. 后续去各个科室进行检查, 诊断, 开药等操作, 都不必再出示身份证了, 只要凭就诊卡即可识别出当前患者的身份.
  3. 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的身份和就诊卡的关联就销毁了. (类似于网站的注销操作)
  4. 又来看病, 可以办⼀张新的就诊卡, 此时就得到了⼀个新的 "令牌" 。
此时在服务器这边就需要记录"令牌"信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作.

2、理解Session

我们先来了解⼀下什么是会话。会话: 对话的意思。

在计算机领域, 会话是⼀个客户与服务器之间的不中断的请求响应。
对客户的每个请求,服务器能够识 别出请求来自于同⼀个客户.
当⼀个未知的客户向Web应用程序发送第⼀个请求时就开始了⼀个会话.
当客户明确结束会话或服务器在⼀个时限内没有接受到客户的任何请求时,会话就结束了。
服务器同⼀时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是从属于哪个用户, 也就是属于哪个会话, 就需要在服务器这边记录每个会话以及与用户的信息的对应关系.
Session是服务器为了保存用户信息而创建的⼀个特殊的对象.
Session的本质就是⼀个 "哈希表", 存储了⼀些键值对结构.
Key 就是SessionID, Value 就是用户信息。

 

SessionId 是由服务器生成的⼀个 "唯⼀性字符串", 从 Session 机制的角度来看, 这个唯⼀性字符串称为 "SessionId". 但是站在整个登录流程中看待, 也可以把这个唯⼀性字符串称为 "token".
上述例子中的令牌ID, 就可以看做是SessionId, 只不过令牌除了ID之外, 还会带⼀些其他信息,比如时间, 签名等。

 可以用下图来理解:

客户端访问服务器,观察cookie 和 session:

1、当用户登陆的时候, 服务器在 Session 中新增⼀个新记录, 并把 sessionId返回给客户端. (通过
HTTP 响应中的 Set-Cookie 字段返回).
2、 客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId . (通过 HTTP 请求中的
Cookie 字段带上).
3、 服务器收到请求之后, 根据请求中的 sessionId在 Session 信息中获取到对应的用户信息, 再进行后续操作;找不到则重新创建Session, 并把SessionID返回。

 Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.

3、Cookie 和 Session 的区别

1、Cookie 是 客户端保存用户信息 的⼀种机制. Session 是 服务器端保存用户信息 的⼀种机制.
2、Cookie 和 Session之间主要是通过 SessionId 关联起来的, SessionId 是 Cookie 和 Session 之间的桥梁。
3、Cookie 和 Session 经常会在⼀起配合使用. 但是不是必须配合 .
  • 完全可以用 Cookie 来保存⼀些数据在客户端. 这些数据不一定是用户身份信息, 也不⼀定是 SessionId。
  • Session 中的sessionId 也不需要非得通过 Cookie/Set-Cookie 传递, 比如通过URL传递。

4、获取Cookie

4.1 传统获取Cookie

代码:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/param")
public class ParamController {@RequestMapping("/m10")public String method10(HttpServletRequest request,HttpServletResponse response){// 获取所有 cookie 信息Cookie[] cookies = request.getCookies();//打印Cookie信息StringBuilder builder = new StringBuilder();if (cookies!=null){for (Cookie ck:cookies) {builder.append(ck.getName()+":"+ck.getValue());}}return "Cookie信息:"+builder;}
} 

Spring MVC是基于 Servlet API 构建的原始 Web 框架, 也是在Servlet的基础上实现的。

HttpServletRequest , HttpServletResponse 是Servlet提供的两个类, 是Spring MVC方法的内置对象. 需要时直接在方法中添加声明即可。
HttpServletRequest 对象代表客户端的请求, 当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息.
HttpServletResponse 对象代表服务器的响应. HTTP响应的信息都在这个对象中, 比如向客户 端发送的数据, 响应头, 状态码等. 通过这个对象提供的方法, 可以获得服务器响应的所有内容。

 此时没有设置Cookie, 通过浏览器访问: http://127.0.0.1:8080/param/m10 ,得到Cookie为null。

我们设置⼀下Cookie的值:
再次访问:

从这个例子中, 也可以看出Cookie是可以伪造的, 也就是不安全的, 所以使用Cookie时, 后端需要进行Cookie校验。

4.2 简洁获取Cookie

代码:

@RequestMapping("/getCookie")
public String cookie(@CookieValue("bite") String bite) {return "bite:" + bite;
}

这种通过注解的方式获取cookie的前提是,已经设置好了cookie或者已经存在cookie了。

访问: http://127.0.0.1:8080/param/getCookie
结果:

5、Session 存储和获取

Session是服务器端的机制, 我们需要先存储 session, 才能获取 session.
Session 也是基于HttpServletRequest 来存储和获取的。

5.1 Session存储

 代码:

@RequestMapping("/setSess")
public String setsess(HttpServletRequest request) {// 获取Session对象HttpSession session = request.getSession();if (session != null) {session.setAttribute("username", "java");}return "session 存储成功";
}
这个代码中看不到 SessionId 这样的概念的. getSession 操作内部提取到请求中的Cookie里的 SessionId, 然后根据SessionId获取到对应的Session 对象, Session 对象用HttpSession来描述。

 获取Session有两种方式:

HttpSession getSession(boolean create);
HttpSession getSession();
HttpSession getSession(boolean create) : 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null。
HttpSession getSession(): 和getSession(true) 含义⼀样 , 默认值为true.
void setAttribute(String name, Object value): 使用指定的名称绑定⼀个对象到该 session 会话。

5.2 Session读取

 读取 Session 可以使用 HttpServletRequest。

代码:

@RequestMapping("/getSess")
public String sess(HttpServletRequest request) {// 如果 session 不存在, 不会⾃动创建HttpSession session = request.getSession(false);String username = null;if (session != null && session.getAttribute("username") != null) {username = (String) session.getAttribute("username");}return "username:" + username;
}
Object getAttribute(String name): 返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null.
我们来运行一下存储session和读取session的代码:
先设置Session: http://127.0.0.1:8080/param/setSess

 通过Fiddler观察Http请求和响应情况:

可以看到, Http响应中, 通过Set-Cookie告知客户端, 把SessionID存储在Cookie中。
通过浏览器, 可以观察到运行结果:

 

获取Session: http://127.0.0.1:8080/param/getSess

我们通过Fiddler观察Http请求和响应

可见,客户端向服务器发出请求时,会带上cookie. (Http请求时, 把SessionId通过Cookie传递到了服务器)

5.3 简洁获取 Session

 方法一:

代码如下:

@RequestMapping("/getSess2")
public String sess2(@SessionAttribute(value = "username",required = false)String username) {return "username:"+username;
}
运行结果: http://127.0.0.1:8080/param/getSess2

 

方法二:通过Spring MVC内置对象HttpSession 来获取

@RequestMapping("/getSess3")
public String sess3(HttpSession session) {String username = (String)session.getAttribute("username");return "username:"+username;
}
HttpSession session = request.getSession();
Session 不存在的话, 会自动进行创建

运行结果: http://127.0.0.1:8080/param/getSess3

对于cookie 和 session 的内容就先介绍到这里了,希望能给你们带来帮助呀!

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

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

相关文章

【Linux】详解软硬链接

一、软硬链接的建立方法 1.1软链接的建立 假设在当前目录下有一个test.txt文件,要对其建立软链接,做法如下: ln就是link的意思,-s表示软链接,test.txt要建立软链接的文件名,后面跟上要建立的软链接文件名…

k8s1.28.8版本配置Alertmanager报警方式(邮件,企业微信)

文章目录 总结部署流程 Alertmanager 三大核心1. 分组告警2. 告警抑制3. 告警静默 报警过滤静默通知方案一:方案二: 抑制报警规则案例一 参考文档 自定义路由告警,分来自不同路由的告警,艾特不同的人员进行区分修改 alertmanager …

linux C:变量、运算符

linux C 文章目录 变量运算符 一、变量 [存储类型] 数据类型 标识符 值 标识符:由数字、字母、下划线组成的序列,不能以数字开头。 数据类型:基本数据类型构造类型 存储类型:auto static…

4月深圳振威新能源产业博览会丨千万订单采购对接会!

4月深圳振威新能源产业博览会丨千万订单采购对接会! 目前,振威新能源海外招商团队已成功与俄罗斯、泰国多家组织机构建立合作联系!已确定携多家知名企业到现场采购! 电池与储能 同时,振威新能源团队也成功与泰国储能技…

【KingSCADA】播放语音

1.函数介绍 PlaySound(string strWaveFileName, int nMode);下面是官方帮助文档中的解释: 2.生成语音文件 3.使用脚本播放音频文件 将音频文件存放在工程目录下面,我存放在了…\Resources\文件夹下: 我简单的写了一个定时1分钟播放一次语…

Docket常见的软件部署1

1 安装MySQL # 查看MySQL镜像 docker search mysql # 拉起镜像 docker pull mysql:5.7 # 创建MySQL数据映射卷,防止数据不丢失 mkdir -p /hmoe/tem/docker/mysql/data/ # 启动镜像 docker run -d --name mysql -e MYSQL_ROOT_PASSWORD123456 -p 3306:3306 -v /home…

蓝桥杯第七届大学B组详解

目录 1.煤球数量; 2.生日蜡烛; 3.凑算式 4.方格填数 5.四平方和 6.交换瓶子 7.最大比例 1.煤球数量 题目解析:可以根据题目的意思,找到规律。 1 *- 1个 2 *** 3个 3 ****** 6个 4 ********** 10个 不难发现 第…

OSCP靶场--Internal

OSCP靶场–Internal 考点(CVE-2009-3103) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.216.40 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-31 07:00 EDT Nmap scan report for 192.168.216.40 Host is up…

C++11新特性(二):更好用的 lambda 表达式和 function 包装器

目录 lambda 表达式 基本格式及参数列表 对于 lambda 捕捉列表的说明 function 包装器 bind 包装器 lambda 表达式 C11引入了lambda表达式,它是一种用于创建匿名函数的语法。lambda表达式可以被视为一个匿名函数对象,它可以在需要函数对象的地方使用…

PyTorch 教程-快速上手指南

文章目录 PyTorch Quickstart1.处理数据2.创建模型3.优化模型参数4.保存模型5.加载模型 PyTorch 基础入门1.Tensors1.1初始化张量1.2张量的属性1.3张量运算1.3.1张量的索引和切片1.3.2张量的连接1.3.3算术运算1.3.4单元素张量转变为Python数值 1.4Tensor与NumPy的桥接1.4.1Tens…

系统慢查询的思考

系统慢查询的思考 在一个系统中发现慢查询的功能或很卡的现象。你是怎么思考的?从哪几个方面去思考?会用什么工具? 一个系统使用了几年后都可能会出现这样的问题。原因可能有以下几点。 数据量的增加。系统中平时的使用中数据量是有一个累…

【AXIS】AXI-Stream FIFO设计实现(四)——异步时钟

前文介绍了几种同步时钟情况下的AXI Stream FIFO实现方式,一般来说,FIFO也需要承担异步时钟域模块间数据传输的功能,本文介绍异步AXIS FIFO的实现方式。 如前文所说,AXI-Stream FIFO十分类似于FWFT异步FIFO,推荐参考前…

MIPI CSI-2 Low Level Protocol解读

一、Low Level Protocol介绍 LLP 是一种面向字节的基于数据包的协议,支持使用短数据包和长数据包格式传输任意数据。为简单起见,本节中的所有示例均为单通道配置。 LLP特性: 传输任意数据(与有效载荷无关) 8 位字大…

Chatgpt掘金之旅—有爱AI商业实战篇(二)

演示站点: https://ai.uaai.cn 对话模块 官方论坛: www.jingyuai.com 京娱AI 一、前言: 成为一名商业作者是一个蕴含着无限可能的职业选择。在当下数字化的时代,作家们有着众多的平台可以展示和推广自己的作品。无论您是对写书、文…

MSPF5438数据卫星透传

最近在网上找了个项目来做,实现功能简单描述就是通过Lora模块E30-170T27D接收上位机发送的数据包,并对接收数据包进行正确性校验,若数据包校验成功则将其储存在W25Q125FV 中,待上位机发送数据包传输完毕指令后,单片机启…

Docker配置Mysql

1.首页搜索mysql镜像 2.选择对应版本的MySQL,点击pull 3.pull完成以后,点击images,这里可以看到刚刚pull完成的mysql版本 4.打开命令界面,运行命令 docker images ,查看当前已经pull的images 5.运行命令设置mysql docker run -it…

【有芯职说】数字芯片BES工程师

一、 数字芯片BES工程师简介 今天来聊聊数字芯片BES工程师,其中BES是Back End Support的缩写,就是后端支持的意思。其实这个岗位是数字IC前端设计和数字IC后端设计之间的一座桥,完成从寄存器传输级设计到具体工艺的mapping和实现。这个岗位在…

Linux文件(系统)IO(含动静态库的链接操作)

文章目录 Linux文件(系统)IO(含动静态库的链接操作)1、C语言文件IO操作2、三个数据流stdin、stdout、stderr3、系统文件IO3.1、相关系统调用接口的使用3.2、文件描述符fd3.3、文件描述符的分配规则3.3、重定向3.4、自制shell加入重…

HCIP【GRE VPN、MGRE VPN与PPP验证综合实验】

目录 实验要求: 实验拓扑图: 实验思路: 实验步骤: 一、配IP地址 (1)配置所有设备接口的IP地址: (2)配置私网与公网接口的缺省路由使得公网可通: 二、P…

前端面试题---->JavaScript

const声明的对象属性和数组的值可以被修改吗?为什么 原因:当使用const声明一个对象或数组时,实际上是保证了对象或数组的引用不会被修改,但对象或数组本身的属性或元素是可以被修改的。这是因为const只能保证指向的内存地址不变&a…