13-Cookie、Session、Token

news2024/11/19 4:14:18

目录

1.前置知识——HTTP协议

1.1.HTTP 的主要特点有以下 5 个:

1.2.HTTP 组成

1.3.为什么会有Cookie、Session、Token?

2.Cookie

3.Session

PS:Cookie 和 Session 的联系与区别

4.Token

4.1.token的组成

4.2.token是如何生成的?

4.3.token认证流程

5.小结

6.核心方法

6.1.HttpServletRequest 类中的相关方法

6.2.HttpServletResponse 类中的相关方法

6.3.HttpSession 类中的相关方法

6.4.Cookie 类中的相关方法

PS:代码实战

①cookie写入和读取

②session写入和读取


1.前置知识——HTTP协议

HTTP(Hyper Text Transfer Protocol)超文本传输协议,下文简称 HTTP,它的作用是用于实现服务器端和客户端的数据传输的。它可以传输任意的数据类型,如文本、HTML、图片、文件、声音等类型。 简单来说,HTTP 的作用就像一个“快递”一样,用来承载客户端(浏览器)和服务器端的数据传输,如下图所示:

1.1.HTTP 的主要特点有以下 5 个:

  1. 简单快速:客户端向服务器端发送请求时,只需传递请求方法、路径和请求参数,因为协议简单,所以使得 HTTP 服务器的程序规模小,因而通信速度很快。
  2. 无连接:所谓的无连接指的是,每次连接只处理一个请求。服务器处理完客户的请求后,会立即断开连接。
  3. 无状态:HTTP 不会记录每次请求的身份信息,因此前一次请求和后一次请求相互“不认识”。
  4. 可传递任意数据类型:HTTP 允许传输任意数据类型,只需要在请求头中标识数据类型 Content-Type 即可。
  5. 一对一通讯:每次 HTTP 请求,都是一个客户端对应一个服务器端。

1.2.HTTP 组成

  1. 请求对象 Request(客户端请求)。
  2. 响应对象 Response(服务器响应)。

每次 HTTP 请求都是由一次请求和一次响应构成的,如下图所示:

1.3.为什么会有Cookie、Session、Token?

HTTP协议是无状态协议,所谓的无状态是指:默认情况下 HTTP 协议的客户端和服务器之间的这次通信,和下次通信之间没有直接的联系。客户端每次想要与服务端通信,都必须重新与服务端链接。

但是实际开发中,很多时候是需要知道请求之间的关联关系的,需要判断两次请求是否同一个人。

例如登陆⽹站成功后,第⼆次访问的时候服务器就能知道该请求是否是已经登陆过了。

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

为了解决这个问题,就迫切需要一种方式知道发起请求的客户端是谁?此时就有了Cookie、Session、Token,它们就可以解决客户端标识的问题。

2.Cookie

cookie是保存在客户端或者浏览器端的一小块数据,大小限制在4KB左右。

那么如何通过cookie来实现用户确定或者权限确定呢?以网站用户登录操作为例:

看到大致可以分为以下几个步骤:

  1. 客户端发送请求到服务端(比如登录请求)。
  2. 服务端收到请求后生成一个session会话。
  3. 服务端响应客户端,并在响应头中设置Set-Cookie。
  4. 客户端收到请求后,如果服务器给了Set-Cookie,那么下次浏览器就会在请求头中自动携带cookie。
  5. 客户端发送其它请求,自动携带cookie,cookie中携带有用户信息等。
  6. 服务端接收到请求,验证cookie信息。比如通过sessionId来判断是否存在会话,存在则正常响应。

举个例子:

  1. 到了医院先挂号,挂号时候需要提供身份证,同时得到了⼀张 "就诊卡",这个就诊卡就相当于患者的 "令牌"。
  2. 后续去各个科室进⾏检查,诊断,开药等操作,都不必再出示身份证了,只要凭就诊卡即可识别出当前患者的身份。
  3. 看完病了之后,不想要就诊卡了,就可以注销这个卡。此时患者的身份和就诊卡的关联就销毁了。 (类似于⽹站的注销操作)
  4. ⼜来看病,可以办⼀张新的就诊卡,此时就得到了⼀个新的 "令牌"。

3.Session

在上⾯的例⼦中,就诊卡就是⼀张 "令牌",要想让这个令牌能够生效,就需要医院这边通过系统记录每个就诊卡和患者信息之间的关联关系。

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

这个就是 Session 会话机制所做的⼯作。会话的本质就是⼀个 "哈希表",存储了⼀些键值对结构。key 就是令牌的 ID(token/sessionId),value 就是⽤户信息。(⽤户信息可以根据需求灵活设计)

  • session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里面有没有包含 sessionId 标识。
  • 如果包含了 sessionId,则代表服务端已经和客户端创建过 session,然后就通过这个 sessionId 去查找真正的 session。
  • 如果没找到,则为客户端创建一个新的 session,并生成一个新的 sessionId 与 session 对应。
  • 然后在响应的时候将 sessionId 给客户端,通常是存储在 cookie 中。
  • 如果在请求中找到了真正的 session,验证通过,正常处理该请求。

总之每一个客户端与服务端连接,服务端都会为该客户端创建一个 session,并将 session 的唯一标识 sessionId 通过设置 Set-Cookie 头的方式响应给客户端,客户端将 sessionId 存到 cookie 中。

sessionId 是由服务器⽣成的⼀个 "唯⼀性字符串"。

从 session 机制的⻆度来看,这个唯⼀性字符串称为 "sessionId"。

但是站在整个登录流程中看待,也可以把这个唯⼀性字符串称为 "token"。

sessionId 和 token 就可以理解成是同⼀个东⻄的不同叫法。(不同视⻆的叫法)

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

通常情况下,cookie 和 session 都是结合着来用,当然也可以单独只使用 cookie 或者单独只使用 session,这里就将 cookie 和 session 结合着来用。过程图如下:

PS:Cookie 和 Session 的联系与区别

一、联系:

从前面可以看出,cookie和session之间主要是通过sesssionId关联起来的,所以:sessionId是cookie和session之间的桥梁。换个说法,session是基于cookie实现的。

二、区别:

  • cookie 是客户端的机制,session 是服务器端的机制。所以session比cookie更加安全。
  • cookie只支持存储字符串数据,session可以存储任意数据。
  • cookie的有效期可以设置较长时间,session有效期都比较短。
  • session存储空间很大,cookie有限制。
  • cookie 和 session 经常会在⼀起配合使用(session会将会话id存储到cookie中)。但是不是必须配合。
  1. 完全可以⽤ cookie 来保存⼀些数据在客户端,这些数据不⼀定是⽤户身份信息,也不⼀定是 token / sessionId。
  2. Session 中的 token / sessionId 也不需要⾮得通过 cookie / Set-Cookie 传递。

4.Token

前面说的 sessionId 可以叫做令牌,令牌顾名思义就是确认身份的意思,服务端可以通过令牌来确认身份。

使用cookie和session有以下缺点:

  1. 增加请求体积,浪费性能,因为每次请求都会携带 cookie。
  2. 增加服务端资源消耗,因为每个客户端连接进来都需要生成 session,会占用服务端资源的。
  3. 容易遭受 CSRF 攻击,即跨站域请求伪造。
  4. 所以就有了民间的认证方式,token方式。

4.1.token的组成

token 其实就是一串字符串而已,只不过它是被加密后的字符串,它通常使用 uid(用户唯一标识)、时间戳、签名以及一些其它参数加密而成。将 token 进行解密就可以拿到诸如 uid 这类的信息,然后通过 uid 来进行接下来的鉴权操作。

4.2.token是如何生成的?

前面说 cookie 是服务端设置了 set-cookie 响应头之后,浏览器会自动保存 cookie,然后下一次发送请求的时候会自动把 cookie 携带上。但是说 cookie 算是一种民间的实现方式,所以说浏览器自然不会对它进行成么处理。token 主要是由服务器生成,然后返回给客户端,客户端手动把 token 存下来,比如利用 localstorage 或者直接存到 cookie 当中也行。

4.3.token认证流程

  1. 客户端发送请求,比如用户输入用户名和密码后登录。
  2. 服务器端校验用户名和密码后,将用户id和其它信息进行加密,生成token。
  3. 服务端将token响应给客户端。
  4. 客户端收到响应后将token存储下来。
  5. 下一次发送请求后需要将token携带上,比如放在请求头中或者其他地方。
  6. 服务端取到token后校验,校验通过后则正常返回数据。

用图进行显示,如下:

5.小结

6.核心方法

6.1.HttpServletRequest 类中的相关方法

6.2.HttpServletResponse 类中的相关方法

6.3.HttpSession 类中的相关方法

⼀个 HttpSession 对象⾥⾯包含多个键值对,我们可以往 HttpSession 中存任何我们需要的信息。

6.4.Cookie 类中的相关方法

每个 Cookie 对象就是⼀个键值对。

  • HTTP 的 Cooke 字段中存储的实际上是多组键值对,每个键值对在 Servlet 中都对应了⼀个 Cookie 对象。
  • 通过 HttpServletRequest.getCookies() 获取到请求中的⼀系列 Cookie 键值对。
  • 通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对。

PS:代码实战

①cookie写入和读取

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalTime;

@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {
    /**
     * 写cookie到客户端
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("myCookie", "Bite:" + LocalTime.now());
        //将cookie发送到前端
        resp.addCookie(cookie);
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().println("cookie添加成功!");
    }

    /**
     * cookie读取
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        StringBuilder builder = new StringBuilder();
        if(cookies != null && cookies.length > 0) {
            for (Cookie  item : cookies) {
                builder.append(item.getName() + ":" + item.getValue() + "<br>");
            }
        }
        //将cookie发送到前端
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().println(builder.toString());
    }
}

当更换浏览器后,cookie就没了。因为cookie是写入到当前的客户端的,不同的客户端,cookie不同。

②session写入和读取

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
public class User {
    private int id;
    private String name;
    private String password;
    private int age;
    //...
}
import model.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/sess")
public class SessionServlet extends HttpServlet {
    private static final String SESSION_USER_KEY = "SESSION_USER_KEY";

    /**
     * 读session
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf-8");
        //1.得到session对象
        HttpSession session = req.getSession(false);
        //false表示有会话,返回session对象,没有会话,返回null
        //true表示有会话,返回session对象,没有会话,创建一个会话,会话在程序中就代表是否登录
        if(null == session) {
            //没有登录
            resp.getWriter().println("抱歉:尚未登录!");
        } else {
            //已登录,打印用户的信息
            //2.从session中得到关联的对象
            User user = (User) session.getAttribute(SESSION_USER_KEY); //①得到所有的cookie;②匹配你的token;③根据value匹配映射的对象
            resp.getWriter().println("登录成功 | " + user);
        }
    }

    /**
     * 写session
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf-8");
        String result = "操作失败!";
        //1.得到session
        HttpSession session = req.getSession(true);
        if(null != session) { //得到(或创建)会话
            //2.将用户对象存储到session
            User user = new User();
            user.setName("admin");
            user.setPassword("admin");
            session.setAttribute(SESSION_USER_KEY, user); //①生成token(sessionId);②token关联到用户对象;③发送存储cookie信息到客户端(token)
            result = "session 写入成功!";
        }
        resp.getWriter().println(result);
    }
}

注意观察cookies由1变为了2。因为session是依靠了cookie存储会话id的。

此处也可以在其他浏览器上进行伪造:

当重启服务器后,会话就没了,浏览器重新访问:

再次用Postman发送请求:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【广州华锐互动】VR航天航空体验展厅提供沉浸式的展示效果

VR航天航空体验展厅是一种基于虚拟现实技术的在线展览形式&#xff0c;它通过模拟真实的太空环境&#xff0c;为用户提供了一种身临其境的参观体验。与传统的线上展览相比&#xff0c;VR航天航空体验展厅具有以下几个特色&#xff1a; 1.沉浸式体验&#xff1a;VR航天航空体验…

史上最详细的webrtc-streamer访问摄像机视频流教程

目录 前言 一、webrtc-streamer的API 二、webrtc-streamer的启动命令介绍 1.原文 2.译文 三、webrtc-streamer的安装部署 1.下载地址 https://github.com/mpromonet/webrtc-streamer/releases 2.windows版本部署 3.Linux版本部署 四、springboot整合webrtc-streamer …

技术不断变革,亚马逊云科技中国峰会引领企业重塑业务

过去十年&#xff0c;数字化转型的浪潮携带着机遇和挑战席卷而来&#xff0c;几乎每个企业都在做数字化转型&#xff0c;开始向大数据、人工智能等新技术寻求生产力的突破。但随着数字化转型深入&#xff0c;很多企业开始感受到数字化投入的成本压力&#xff0c;加之新技术正带…

Alibi:Attention With Linear Biases Enables Input Length Extrapolation

Alibi:Attention With Linear Biases Enables Input Length Extrapolation IntroductionMethodResult参考 Introduction 假设一个模型在512token上做训练&#xff0c;在推理的时候&#xff0c;模型在更长的序列上表现叫做模型的外推性。作者表明以前的位置编码如Sin、Rotary、…

JS 数据变化监听函数封装

文章目录 监听函数使用用例重复添加函数&#xff0c;只有最后一个监听函数有效 监听函数 /*** 监听函数* param {对象} vm * param {键值} key * param {触发函数} action */ function WatchValueChange(vm, key, action) {var val vm[key]Object.defineProperty(vm, key, {e…

阿里内部流传出来的《1000 道互联网大厂 Java 工程师面试题》来袭,面试必刷,跳槽大厂神器

眼看着"金九银十"也快到来了&#xff0c;很多小伙伴都蠢蠢欲动想要刚给自己涨一波薪资&#xff1b;面试作为涨薪最直接最有效的方式&#xff0c;我们需要花费巨大的精力和时间来准备。除了自身的技术积累之外&#xff0c;掌握一定的面试技巧和熟悉最常见的面试题&…

掌握imgproc组件:opencv-图像轮廓与图像分割修复

图像轮廓与图像分割修复 1.查找并绘制轮廓1.1 寻找轮廓&#xff1a;findContours()函数1.2 绘制轮廓&#xff1a;drawContours()函数1.3 案例程序&#xff1a;轮廓查找 2. 寻找物体的凸包2.1 凸包2.2 寻找凸包&#xff1a;convexHull()函数2.3 案例&#xff1a;寻找和绘制物体的…

【前端|CSS系列第1篇】CSS零基础入门之CSS的基本概念和选择器

欢迎来到CSS零基础入门系列的第一篇博客&#xff01;在这个系列中&#xff0c;我们将一起学习CSS&#xff08;层叠样式表&#xff09;的基础知识&#xff0c;探索如何为网页添加样式和布局。本篇博客将重点介绍CSS的基本概念和选择器&#xff0c;帮助你理解CSS的核心概念。 1.…

MAYA活塞(使用骨骼)

复制骨骼 P父子关系 创建组

根据数组中对象的某个字段分组最简洁方式

使用map数据结构的&#xff0c;键值唯一性进行操作 //根据年龄分组&#xff0c;获取目标数据格式//[{key:key,data:[{}]}]//{key:[]}const arr [{ name:test1,age:10},{ name:test2,age:20},{ name:test3,age:10},{ name:test4,age:20},{ name:test5,age:10},{ name:test6,age…

群晖 NAS WebDAV服务手机ES文件浏览器远程访问

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址6. 使用固定地址测试连接 转载自cpolar极点云文章&#xff1a;群晖NAS搭建WebDAV服务手机ES文件浏览器远程访问 有时候我们想通过移动设备访问群晖NAS 中的文件,以满足特殊需求,…

centos7安装zabbix v4

1.获取rpm包 wget -c https://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/x86_64/zabbix-release-4.0-2.el7.noarch.rpm 2.安装 yum install zabbix-release-4.0-2.el7.noarch.rpm -y 3.关防火墙和selinux 4.下载数据库 yum install mariadb -y 5.启动数据库设置密码 …

UE4 Cesium离线生成地形

地理空间数据云 首先进这个网址&#xff0c;下载对应的tif以及高程&#xff08;DEM&#xff09; 下载CesiumLab2 在地形切片中点击添加&#xff0c;将黑白图像数据&#xff0c;添加&#xff0c;选择存储类型为散列文件&#xff0c;选择输出路径 再选择影像切片&#xff0c;选择…

Redis 数据类型 | Navicat 数据编辑器

Redis 有别于其他键值&#xff08;key-value&#xff09;存储的一个关键特性是它支持多种数据类型&#xff0c;包括字符串&#xff08;string&#xff09;、列表&#xff08;list&#xff09;、集合&#xff08;set&#xff09;、排序集合&#xff08;sorted set&#xff09;和…

Sparse Fuse Dense: 向高质量的深度补全3D目标检测迈进

点云的稀疏性&#xff1a;在远距离和遮挡区域提供的信息较差&#xff0c;导致难以生成精确的3D边界框。 出现了多模态融合。 图像和点云的不同表示方式使得它们难以融合&#xff0c;导致性能不佳。 论文提出了一种新颖的多模态框架SFD&#xff08;Sparse Fuse Dense&#xf…

Docker学习笔记14

容器镜像在Docker host的存储位置&#xff1a; 最上面的层&#xff08;layer&#xff09;为读写层&#xff0c;也就是容器。下面的其他的层都是只读层的镜像层。并且除了最下面的一层外&#xff0c;其他的层都有一个指针指向自己下面的一层镜像&#xff08;联合文件系统&#…

SpringMVC入门篇2 --- 请求与响应

目录 1.请求映射路径 在类上面统一设置RequestMapping注解&#xff0c;统一设置访问路径前缀。 在上文案例的基础上进行修改。 src/main/java/org/example/controller/UserController.java package org.example.controller;import org.springframework.stereotype.Controll…

寻寻觅觅,彩电厂商能否“智”取未来?

彩电业&#xff0c;还能不能好&#xff1f; 电视行业的发展&#xff0c;一直伴随着漫长的价格战。从黑白到彩电再到超大屏&#xff0c;从CRT到平板再到液晶&#xff0c;在每一轮技术革新之后&#xff0c;市场总会经历从落到起&#xff0c;从起到落的循环&#xff0c;然后陷入价…

重磅!2023年影响因子正式发布 , Nature/Science等顶刊普遍下降 (附名单下载)~

2023年6月28日&#xff0c;科睿唯安&#xff08;Clarivate Analytics&#xff09;发布了最新年度期刊引证报告(JCR), 其中包含我们所关注的最新影响因子(Impact Factor, IF). 科研界对每年影响因子发布可谓是翘首以待&#xff0c;据小编统计发现&#xff0c;今年的影响因子普遍…

安科瑞故障电弧探测器在建筑电气的设计与应用

安科瑞 崔丽洁 【摘要】&#xff1a;电气设备是建筑中不可缺少的一部分&#xff0c;具有较为重要的作用和意义&#xff0c;在应用过程中不仅能够提升建筑本身实用性能&#xff0c;而且可为消费者提供更加优良的生活环境。但设备一旦在运行过程中出现故障&#xff0c;不仅会影响…