cookie 和 session 的恩恩怨怨

news2024/11/24 6:58:36

目录

1. Cookie 从哪里来?

2. Cookie 到哪里去?

3. Cookie 有啥用?

Session

Session 中的常用方法

模拟实现一个登录页面:

session 和  cookie 的最官方的恩恩怨怨


Cookie 是浏览器在本地存储数据的一种机制

1. Cookie 从哪里来?

  • Cookie 从服务器来
  • 服务器在响应中带有 Set-Cookie 字段, 通过这个字段就可以把要保存在浏览器本地的数据给返回回去

2. Cookie 到哪里去?

  • 后续浏览器访问服务器的时候, 就会把当前本地的所有cookie 都通过 http 请求, 给带过去

3. Cookie 有啥用?

  • 最典型的一种应用, 就是使用 cookie保存当前用户的登录状态(用户身份信息)

在 cookie 保存用户身份标识这样的应用场景中, 此时身份标识如何分配, 以及身份信息具体如何存储(session会话), 都是需要服务器的支持的


Session

Session 就是服务器这边用来实现用户身份区分的一种机制, 通常是和 cookie 配合使用的

        给当前的用户分配一个 sessionId 同时记录下当前用户的一些身份信息(可以自定义的) SessionId  就会被返回到浏览器的 cookie 中后续浏览器访服务器都会带着这个sessionId,从而能够让服务器识别出当前用户身份了

Session 中的常用方法

HttpSession getSession()  :

在服务器中获取会话, 参数如果为 true ,则当不存在会话时新建会话, 单数如果为 false ,则当不存在会话时返回 null

详解:

1. getSession() 有一个参数, boolean

如果参数为 false , getSession 的行为是:

  • 读取请求中 cookie 里的 sessionId
  • 在服务器这边根据 sessionId 来查询对应的 Session 对象
  • 如果查到了, 就会直接返回这个 session 对象 , 如果没查到, 返回 null

如果参数为 true , getSession 的行为是:

  • 读取请求中 cookie 里的 sessionId
  • 在服务器这边根据 sessionId 来查询对应的 Session 对象
  • 如果查到了, 就会直接返回这个 session 对象
  • 如果没查到, 就会创建一个 Session 对象, 同时生成一个 sessionId

以 sessionId 为 key ,Session 对象为 value, 把这个键值对存储到服务器里的一个 hash 表中, 同时把 sessionId 以 Set-Cookie 的方式返回给服务器

2. session.invalidate();

这个方法就是将session中的变量全部清空

3. session.setAttribute(key,value);

设置属性 key ,value

4. session.getAttribute(key);

获取key的值

5.session.removeAttribute(key);

删除属性为key的值

多用于实现登录功能,我们直接  ⬇  

模拟实现一个登录页面:

提供两个页面 :

1. 登录页面

  • 两个输入框(用户名及密码)
  • 一个登录按钮

2. 主页 显示即可

服务器处理这个请求的时候就会验证用户名和密码

如果用户名密码正确, 就会跳转到主页, 并且在页面上欢迎和访问次数

第一步:

实现登录页面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>-登录页面-</title>
</head>

<body>
    <form action="login" method="post">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" value="登录">
    </form>
</body>

</html>

 

Form 会组织这里的数据以键值对的形式提交给服务器

  • 其中 key 就是 input 的 name 属性        

        其中 value 就是 input 用户输入的内容

        最终会构造成 post 请求, 在 body 里以键值对(类似于 query String) 的格式, 进行组织

        服务器可以通过 getParameter 来获取到指定 key 的 value

第二步

编写 LoginServlet 处理上述登录请求

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 先从请求中拿到用户名和密码
        // 为了保证读出来的参数也能支持中文, 要记得设置请求的编码方式是 utf8
        req.setCharacterEncoding("utf8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //2. 验证用户名和密码是否正确
        if (username == null || password == null || username.equals("") || password.equals("")) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前输入的用户名和密码不能为空!");
            return;
        }
        //3. 假定用户名是 张三 或者 李四 . 密码是 122
        //正常的登录逻辑, 验证用户名个密码都是从数据库读取的
        if (!username.equals("张三") && !username.equals("李四")) {
            //用户名有问题
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("用户名或密码有误");
            return;
        }
        if (!password.equals("122")) {
            //密码有问题
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("用户名或密码有误");
            return;
        }
        //3. 用户名和密码验证 OK , 接下来就创建一个会话
        //用户还没有进行登录, 测试请求的 cookie 中没有 sessionId
        //这时候 getSession 是无法从服务器的 哈希表 中找到该session 对象的
        //但是我们参数设为了 true , 这时候就允许 getSession 在查询未果的情况下, 创建新的 session 对象和 sessionId
        //并且会自动把这个 sessionId 和 session 对象存储在 哈希表 中
        //同时返回这个 session 对象, 并且 在接下来的响应中会自动把这个 sessionId 返回给客服端浏览器
        HttpSession session = req.getSession(true);
        //接下来可以让刚刚创建好的 session 对象存储咱们自定义的数据, 就可以在这个对象中存储用户的身份信息
        session.setAttribute("username", username);  //这个时间胶囊 我们在进入主页的时候就可以 挖啊挖
        //4. 登录成功之后 , 自动跳转到 主页
        resp.sendRedirect("index");
    }
}

小结:

 登录逻辑的固定套路:

  1. 读取用户名和密码
  2. 验证用户名和密码
  3. 创建会话 , 保存必要的用户信息
  4. 重定向到主页

第三步

编写生成主页的 Servlet

package login;

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;


//这个 Servlet 用来动态的生成主页面
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //此处禁止创建会话, 如果没有找到, 认为用户是未登录的状态
        //如果找到了才认为是登录状态
        HttpSession session = req.getSession(false);
        if(session == null) {
            //未登录状态
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前用户未登录!");
            return;
        }
        String username = (String) session.getAttribute("username");
        if(username == null) {
            //虽然会话有对象, 但是里面没有必要的属性, 也是认为登录状态异常
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前用户未登录!");
            return;
        }
        //如果上述的检查都 OK , 就直接生成一个动态页面
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write("欢迎" + username + "进入 vvvvip 厅" );
    }
}

 

通过抓包可以看见 cookie 就创建出来了

上面的 session  也不会一直存下去,服务器重新启动的时候, 原来 hash 表中的内容也就没了

此时再次访问, 就可能出现 sessionId 无法查询到, 于是就会被识别成 未登录状态

服务器默认保存会话, 是在内存中的, 一旦重启服务器, 之前的会话数据就没了

但是 smart Tomcat 为了方便程序员调试程序, 会在停止服务器的时候吗把会话持久化保存, 会话不会丢失 (这个取决于 smart Tomcat 版本)

 访问了三次之后, 显示的界面

前面的介绍完了 现在我们来看看 session 和  cookie 的恩恩怨怨 🔽


session 和  cookie 的最官方的恩恩怨怨

Cookie和Session是Web开发中常用的两种技术,用于在服务器和客户端之间存储和跟踪用户数据。它们之间的主要区别如下:

  1. 数据存储位置:

    • Cookie:Cookie是在客户端(通常是浏览器)上存储数据的小型文本文件。服务器将Cookie发送给客户端,然后客户端将Cookie存储在本地。每次客户端向服务器发送请求时,它都会将相关Cookie信息包括在请求头中一起发送给服务器。
    • Session:Session是在服务器上存储数据的一种机制。服务器创建一个唯一的会话标识符(Session ID),并将该标识符与相关数据存储在服务器上。然后,将Session ID发送给客户端(通常通过Cookie),客户端在后续请求中将Session ID包括在请求中发送给服务器。
  2. 存储容量和安全性:

    • Cookie:Cookie的存储容量较小,通常限制在几KB。Cookie中的数据可以由客户端修改,因此不适合存储敏感信息。Cookie可以设置过期时间,在过期之前会一直存在于客户端。
    • Session:由于Session数据存储在服务器上,因此可以存储更多的数据,并且相对更安全。Session数据在客户端不可修改,只有服务器可以访问和修改。Session可以在一段时间后过期或手动删除。
  3. 生命周期:

    • Cookie:Cookie可以设置一个特定的过期时间,也可以设置为会话Cookie(浏览器关闭后自动删除)。如果没有设置过期时间,Cookie将一直保留在客户端,直到被删除或过期。
    • Session:Session可以在客户端关闭浏览器后继续保持,因为Session数据存储在服务器上。服务器可以设置Session的超时时间,以确保在一段时间内没有活动后,Session数据可以自动删除。
  4. 扩展性:

    • Cookie:Cookie可以在不同的域名和路径之间共享,因此可以在多个网站之间跟踪用户。Cookie还可以设置为跨子域共享,但存在一些限制。
    • Session:Session默认情况下与特定的域名和路径绑定。如果需要在多个域名或路径之间共享Session数据,需要进行额外的配置。

        总体而言,Cookie适合存储小量非敏感数据,并在客户端之间进行共享。而Session适合存储较大量的敏感数据,因为数据存储在服务器上并且在客户端之间不可修改。选择使用Cookie还是Session取决于具体的应用需求和安全性要求。

 

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

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

相关文章

chatgpt赋能python:Python如何将两张图片横向拼在一起

Python如何将两张图片横向拼在一起 在网页设计中&#xff0c;有时候需要将两张图片横向拼在一起来达到更好的展示效果。本文将介绍如何使用Python实现这一功能。 前置知识 在使用Python进行图像处理之前&#xff0c;先了解以下几个库&#xff1a; Pillow&#xff1a;Python…

chatgpt赋能python:Python如何取非

Python如何取非 Python是一种强大的编程语言&#xff0c;可以用于许多不同的任务&#xff0c;包括搜索引擎优化&#xff08;SEO&#xff09;。在这篇文章中&#xff0c;我们将重点介绍Python如何取非&#xff0c;这对于SEO优化非常重要。 什么是取非&#xff1f; 在SEO中&am…

chatgpt赋能python:Python如何手动安装包:技术向SEO文章

Python如何手动安装包&#xff1a;技术向SEO文章 虽然大多数Python用户都习惯使用pip来安装和管理包&#xff0c;但手动安装包是必要的技能之一。这篇文章将介绍如何使用Python的标准方法手动安装包&#xff0c;并提供实际的指导。 为什么要手动安装包&#xff1f; 有时候&a…

达梦数据库读写分离集群搭建

目录 说明... 3 前期准备... 4 开始搭建读写分离... 5 一、主库200. 5 1、卸载原实例... 5 2、创建新的实例... 6 3、配置主库200. 6 4、启动主库... 8 5、设置OGUID.. 8 二、配置2台备库... 9 1、创建新的实例... 9 2、备份恢复&#xff08;初始化实例后应该先备份…

VS2012编译VTK7.1.1库,使用VTK加载显示STL图像

文章目录 cmake配置项目编译VTK库代码测试报错:no override found for vtkpolydata下载VTK库下载地址,下载VTK源码 https://vtk.org/download/ 需要工具 1.VS2012 2.CMAKE 官网 https://cmake.org/ cmake配置项目 下载后的vtk7.1.1库解压 安装好cmake,打开cmake-gui,在whe…

chatgpt赋能python:Python循环语句详解:如何循环执行一个语句

Python循环语句详解&#xff1a;如何循环执行一个语句 Python是一种简单易学、优雅高效的编程语言&#xff0c;在很多领域都有广泛应用。其中&#xff0c;循环语句特别重要&#xff0c;可以让我们轻松实现重复执行某个语句的功能。本文将介绍Python的循环语句及其应用场景&…

01:快速入门爬虫

1.引导 1.Robots协议 Robots协议&#xff08;爬虫协议&#xff09;的全称是“网络爬虫排除标准”&#xff08;Robots Exclusion Protocol&#xff09;&#xff0c;网站通过Robots协议告诉搜索引擎哪些页面可以抓取&#xff0c;哪些页面不能抓取。该协议是国际互联网界通行的道…

Pytorch1.12.1+cu113安装记录

因为torch1.7.0对于SiLU算子导出不支持,需要1.7.1才支持.于是索性准备更新一下自己的算法版本库,查询到CUDA11.3支持的最高Pytorch版本为1.12.1,于是统一做一下更新.这里采用离线下载的方式,因为在线下载实在是太蛋疼了 1. Pytorch离线包下载 这是官方提供的版本,我这里不直接…

Python-web开发学习笔记(4):CSS基础

&#x1f680; Python-web开发学习笔记系列往期文章&#xff1a; &#x1f343; Python-web开发学习笔记&#xff08;1&#xff09;--- HTML基础 &#x1f343; Python-web开发学习笔记&#xff08;2&#xff09;--- HTML基础 &#x1f343; Python-web开发学习笔记&#xff08…

面试常考算法(1):反转链表、局部反转链表(包含误区分析)

BM1 反转链表 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;&#xff0c;$ 长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。   数据范围: 0 ≤ n ≤ 1000 0 \leq n \leq 1000 0≤n≤1000   要求: 空间复杂度 O ( 1 ) O(1) O(1) &#xff0c…

QT QHorizontalSpacer弹簧控件

本文详细的介绍了QHorizontalSpacer控件的各种操作&#xff0c;例如&#xff1a;新建界面、控件布局、隐藏控件、设置宽高、添加布局、其它参数、.h源文件、cpp源文件、其它文章等等操作。 实际开发中&#xff0c;一个界面上可能包含十几个控件&#xff0c;手动调整它们的位置既…

最优化简明版(上)

引言 本文简单地介绍一些凸优化(Convex Optimization)的基础知识&#xff0c;可能不会有很多证明推导&#xff0c;目的是能快速应用到机器学习问题上。 凸集 直线与线段 设 x 1 ≠ x 2 x_1 \neq x_2 x1​x2​为 R n \Bbb R^n Rn空间中的两个点&#xff0c;那么具有下列形…

基于 log4j2 插件实现统一日志脱敏,性能远超正则替换

前言 金融用户敏感数据如何优雅地实现脱敏&#xff1f; 日志脱敏之后&#xff0c;无法根据信息快速定位怎么办&#xff1f; 经过了这两篇文章之后&#xff0c;我们对日志脱敏应该有了一定的理解。 但是实际项目中&#xff0c;我们遇到的情况往往更加复杂&#xff1a; 1&am…

开发云原生应用应遵循的十二要素

代码库&#xff1a;一份版本控制下的基准代码库&#xff0c;多份部署 应用程序的源代码仓库应该只包含一个应用程序&#xff0c;并列出它所依赖的资源清单。对于不同的环境&#xff0c;我们应该不需要重新编译或打包应用程序。每个环境中特有的设置应该与代码无关 依赖&#…

SpringMVC-【回顾】

回顾MVC架构 什么是mvc&#xff1a;模型、视图、控制器 -----软件设计规范 回顾servlet maven项目导入依赖&#xff08;webmvc,servlet-api,jsp-api,jstl,junit&#xff09;创建子模块&#xff0c;在子模块中添加框架支持&#xff08;在子模块中导入依赖jsp、servlet【因为父…

【NACK】视频rtp包接收及nack触发流程走读

这里大神分析很很透彻了:原文地址:WebRTC中NACK的处理流程 - 资料 - 音视频开发中文网 - 构建全国最权威的音视频技术交流分享论坛视频包的接收 RtpVideoStreamReceiver::ReceivePacket void RtpVideoStreamReceiver::ReceivePacket(const RtpPacketReceived& packet)知乎…

聊聊哪些奇葩的代码规范 —— 代码放一行

因为有些要求感觉实是太过奇葩&#xff0c;收集下来娱乐下大家。 代码规范要求 要求代码必须要放在一行上面&#xff0c;导致代码上面有不少行甚至超过了 1000 个字符。 规范解读 就是有时候代码过长&#xff0c;我们会折行增加可读性&#xff0c;最简单的一个例子就是 obj…

CG平台实验——逻辑回归

文章目录 练习2&#xff1a;逻辑回归介绍1 Logistic回归1.1 数据可视化1.2 实现1.2.1 Sigmoid函数1.2.2 代价函数和梯度1.2.2.1 代价函数1.2.2.2 梯度下降 1.2.3 寻找最优参数1.2.4 评估逻辑回归 2 正则化逻辑回归2.1 数据可视化2.2 特征映射2.3 代价函数和梯度 2.4 寻找最优参…

rust疑难进阶手册(1)-安装和管理,类型推断,打印输出(1)

目录 安装管理和配置工具项目管理类型推断格式输出位置参数格式化文本命名参数安装 不管OS是否带有rust,都应使用rustup来安装rust linux/freebsdcurl https://sh.rustup.rs -sSf | shwindows https://www.rust-lang.org/tools/install windows下建议使用GNU的编译链接库,不…

GraphQL入门实战

解决什么问题 根据请求控制返回结果 例如&#xff1a; 一个User对象&#xff0c;有id&#xff0c;name&#xff0c;mobile&#xff0c;email 有些接口只要返回id,name &#xff0c;有些接口还要要返回 mobile 适用场景 弱文档管理&#xff0c;公司对文档要求不高需求复杂变…