Cookie和Session详解以及结合生成登录效果

news2024/11/20 18:34:51

目录

引言 

1.Cookie中的数据从哪来数据长啥样?

2.Cookie有什么作用?

3.cookie与session的工作关联?

4.Cookie到哪去? 

5.Cookie如何存? 

6.Session 

 7.Cookie与Session的关联与区别

8.通过代码理解 

8.1 相关代码

8.2 观察现象

8.3 总结 

9.Cookie结合Session 实现登录效果

1.前端代码(简易版界面)

2.后端 

3.现象

 4.小结

get和post的区别在这里有介绍: 


引言 

Cookie是浏览器提供的持久化存储数据的机制

1.Cookie中的数据从哪来数据长啥样?

cookie 是从服务器返回给浏览器的;是由程序员代码自定义的键值对结构数据。要在浏览器cookie中保存哪些数据,通过http响应的Set-Cookie字段把键值对写回去

2.Cookie有什么作用?

 Cookie在浏览器中存储临时数据

最典型的应用:存储“身份标识.

3.cookie与session的工作关联?

此处的身份标识(sessionId)就涉及到cookie和session的梦幻联动。

cookie是浏览器存储数据,session是服务器存储数据(存储用户的详细信息,同时给用户分配一个sessionId),此时服务器就把sessionId返回给浏览器,后续再访问浏览器中的页面时就会在请求上自动带上我们的sessionId,进一步服务器就知道哪个用户在操作了。

4.Cookie到哪去? 

Cookie中的内容会在下次访问该网站的时候自动带到http请求中。

5.Cookie如何存? 

cookie存储在浏览器所在的硬盘(往往会存在超时时间)中,浏览器按照不同的域名分别存储cookie,域名和域名之间的cookie不同相互干扰。

cookie在浏览器存储的目的是后续访问服务器的时候,通过请求的header将cookie发送给服务器

作用:因为服务器是同时服务多个客户端的,客户端需要借助cookie来告诉服务器当前提供的服务到哪个环节了,服务器也可以通过cookie识别该客户端

6.Session 

上述服务器生成了一些键值对结构数据,就是session(会话)

生成的唯一的身份序号叫做sessionid,也就是key,value就是记录的身份信息


具体流程:

用户登陆时,服务器在session中添加一个key-value记录,并且将key通过setCookie返回给客户端,客户端存储了cookie信息
客户端后续再发请求到服务器的时候,会通过http的header携带cookie信息
服务器收到请求之后,根据根据请求中的sessionid/token 在s ession 信息中获取到对应的用户信息 ,再决定后续的操作.
 

 7.Cookie与Session的关联与区别

Cookie和Session也是常用的跟踪用户身份和状态管理的机制。它们之间的关联与区别如下:

关联:

  • 在使用Session时,通常会在客户端保存一个名为JSESSIONID的Cookie,用于标识用户会话。
  • 服务器根据JSESSIONID从存储Session的位置(如内存或数据库)中获取对应的数据。

区别:

  • 存储位置:在Java中,HttpSession接口提供了对Session的访问和管理,Session对象默认存储在服务器端,而Cookie存储在客户端。
  • 数据容量:Cookie每个域名下的浏览器对数量和大小都有限制,而Session相对可以存储更多的数据。
  • 生命周期:Cookie可以设置过期时间,可以是临时的或长期有效的;而Session一般在会话结束后自动销毁,也可以手动设置过期时间。
  • 安全性:由于存储在客户端,Cookie存在被篡改和盗用的风险,可以通过设置属性增加安全性;而Session存储在服务器端,相对更安全。
  • 跨域支持:Cookie默认情况下只能在同一域内共享,可以通过设置domain属性实现跨域共享;而Session不受域的限制,可以在不同域之间共享。

在Java Web开发中,通常会使用Servlet API提供的HttpSession对象来管理Session。在登录认证成功后,服务器会创建一个唯一的JSESSIONID,并将相关的用户信息存储在HttpSession对象中,然后将JSESSIONID以Cookie的方式发送给客户端保存。客户端在后续的请求中会携带该Cookie,服务器通过解析Cookie中的JSESSIONID来获取对应的HttpSession对象,从而实现用户身份的认证和状态的保持。


8.通过代码理解 

8.1 相关代码

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;


@WebServlet("/getcookie")
public class GetCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取到这次请求的cookie
        Cookie[] cookies=req.getCookies();
        if(cookies!=null){
            for(Cookie cookie:cookies){
                System.out.println(cookie.getName()+" "+cookie.getValue());

            }
        }else{
            System.out.println( "请求中没有cookie");
        }
        //这里的if else 判断是在网页访问过程,500提示码提示的
        resp.getWriter().write("ok");
    }
}
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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 86180
 * Date: 2023-10-04
 * Time: 23:20
 */
@WebServlet("/setcookie")
public class SetCookieServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //想通过这个方法把自定义的数据返回到浏览器
        Cookie cookie=new Cookie("data","2023-09-23");
        Cookie cookie1=new Cookie("time","09:48");
        resp.addCookie(cookie);
        resp.addCookie(cookie1);
        resp.getWriter().write("setCookie ok");


    }
}

 在pom.xml中从maven仓库https://mvnrepository.com/?__cf_chl_rt_tk=ptb7mN.OmXB2Pdf.tn5HNQSGzovAURAXJ95hEAo9vIA-1696475447-0-gaNycGzNDTs导入servlet和Jackson的对应依赖

8.2 观察现象

通过fiddler抓包就可以看出访问setcookie请求的时候,代码中就会构造cookie放在响应中,

进一步就返回到我们的浏览器中,后续再发请求的时候,我们的cookie就会在请求中

这时2,我们通过getcookie去获取,就可以再idea服务器中看到相应的cookie

8.3 总结 

cookie从服务器来,服务器调用相应的api,就可以给api添加setcookie字段,setcookie字段里面就是我们自定义的键值对,浏览器收到这些键值对,就会把这些键值对保存在浏览器本地,后续再给网站发送请求,就可以把cookie带到header里面 

9.Cookie结合Session 实现登录效果

 每个用户都应该有自己的session,session在服务器中存在很多份,每个服务器同时会有很多session,所以服务器会使用map来组织多个session,就像是一个Map<String,Object>

1.前端代码(简易版界面)

 <!DOCTYPE html>
 <html lang="en">
 <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <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>

 在idea重启服务器后

2.后端 

loginServlet(整体登录背后的逻辑成功登录后跳转)和IndexServlet(通过这个网页生成一个servlet)

/**getSession背后做的事情:
 *💡1.先读取请求中的cookie,看cookie中是否有JSESSIONID属性以及值是啥
 * 如果没有就认为需要创建新的会话;
 * 如果有,就拿着这个id去查询看看当前的session是否存在;
 *   要是session存在,就直接返回该session;
 *   要是session不存在就创建新的会话;
 *💡2.当前确实需要创建会话就会出安检处一个session对象,同时生成一个唯一的JSESSIONID.
 *  以JSESSIONID为key,Session对象为value,把这个键值对给插入到服务器的哈希表中。
 *💡3.刚才生成的JSESSIONID又会通过addCookie方法加入到 响应 中,
 * 此事响应就会带有Set-Cookie字段,这里的值就是JSESSIONID=****,
 * 通过响应,就把JsessionID返回到浏览器
 *
 * **/

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("/login")
public class loginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.先使用getParameter获取到username,password的值
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //验证信息是否正确
        //正常用数据库保存,这里写死
        //2.验证合法:zhangsan  123456
        if(!username.equals("zhangsan")){
            //失败
            //重定向=>登录页
            System.out.println("用户名错误");
            resp.sendRedirect("login.html");
            return;
            /**如果你想在登陆页面也显示出内容,就是如果错误就在页面显示用户名错误;
             * 就getWriter.write()
             * resp.setContentType("text/html;charset = utf8");
             * resp.getWriter().write("用户名错误");
             * 这边未注释的代码是显示到服务器端,在我们idea上就可以看见
             * */
        }
        if(!password.equals("123456")){
            //失败
            System.out.println("密码错误");
            resp.sendRedirect("login.html");
            return;
        }
        //成功

        //3.创建会话
        HttpSession session = req.getSession(true);
        //getSission(true);是拿着sessionId查一下哈希表,
        //如果sessionId不存在.或者没查到,就创建新会话插入到哈希表
        // 查到了就返回查到的结果
        //如何创建?
        //1.构造HttpSession对象
        //2.构造唯一的sessionId
        //3.把这个键值对插入哈希表
        //4.把sessionId设置到响应报文Set-Cookie字段

        //将用户信息保存到session对象中,保存一些自定义数据
        session.setAttribute("username",username);
        session.setAttribute("time",System.currentTimeMillis());
        //4.重定向到主页
        resp.sendRedirect("index");

    }
}写死
        //合法:zhangsan  12345
        if(!username.equals("zhangsan")){
            //失败
            //重定向=>登录页
            System.out.println("用户名错误");
            resp.sendRedirect("login.html");
            return;
            /**如果你想在登陆页面也显示出内容,就是如果错误就在页面显示用户名错误;
             * 就getWriter.write()
             * resp.setContentType("text/html;charset = utf8");
             * resp.getWriter().write("用户名错误");
             * 这边未注释的代码是显示到服务器端,在我们idea上就可以看见
             * */
        }
        if(!password.equals("123456")){
            //失败
            System.out.println("密码错误");
            resp.sendRedirect("login.html");
            return;
        }
        //成功

        //创建会话
        HttpSession session = req.getSession(true);
        //getSission(true);是拿着sessionId查一下哈希表,
        //如果sessionId不存在.或者没查到,就创建新会话插入到哈希表
        // 查到了就返回查到的结果
        //如何创建?
        //1.构造HttpSession对象
        //2.构造唯一的sessionId
        //3.把这个键值对插入哈希表
        //4.把sessionId设置到响应报文Set-Cookie字段

        //将用户信息保存到session对象中,保存一些自定义数据
        session.setAttribute("username",username);
        session.setAttribute("time",System.currentTimeMillis());
        //重定向到主页
        resp.sendRedirect("index");

    }
}
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 86180
 * Date: 2023-10-05
 * Time: 18:05
 */


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 {
        //1.先判定用户登陆状态
        //若没登陆.先登录
        //若登录,根据绘画用户名信息,显示到页面上
        HttpSession session = req.getSession(false);
        //不会触发会话创建
        if(session==null){
            System.out.println("用户未登录");
            resp.sendRedirect("login.html");
            return;
        }
        //2.登陆成功了取出之前的attribute
        String username = (String) session.getAttribute("username");
        Long time=(Long)session.getAttribute("time");
        System.out.println("username"+username+"time"+time);

        //执行到这里,session和post中的是一个对象
        //根据同一个sessionid对应到的对象
        //3.根据这样的内容构造出一个页面
        resp.setContentType("text/html;charset = utf8");
        resp.getWriter().write("欢迎您:" + username+"!上次登录时间"+time);
    }
}

3.现象

登陆成功后效果,登陆失败会在服务器端显示,如果想在页面也显示出来可以在loginServlet中对应位置代码中加上

resp.setContentType("text/html;charset = utf8");
resp.getWriter().write("*****");

通过 session.setAttribute("username",username);也将用户名保存了进去。

 4.小结

 当前这个程序,就涉及到三个部分进行联动~~

1.登陆页面(静态的 html ,使用 form 构造 http 请求)

2. LoginServlet ( doPost 处理登陆的逻辑流程1234)

3. IndexServlet ( doGet 处理主页的生成)

get和post的区别在这里有介绍: 

【http协议与tomcat - CSDN App】http://t.csdnimg.cn/s9K09

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

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

相关文章

c++学习之 继承的方式

在C中&#xff0c;继承方式&#xff08;或继承访问权限&#xff09;有三种&#xff1a;public、protected 和 private&#xff0c;它们决定了派生类&#xff08;子类&#xff09;对基类&#xff08;父类&#xff09;成员的访问权限&#xff0c;它们之间的区别如下&#xff1a; …

局部放电发生因素与局部放电试验的重要性

局部放电发生的几个因素&#xff1a;   ①电场过于集中于某点&#xff1b;   ②固体介质有气泡&#xff0c;有害杂质未除净&#xff1b;   ③油中含水、含气、有悬浮微粒&#xff1b;   ④不同的介质组合中&#xff0c;在界面处有严重的电场畸变。   局部放电试验的重…

【小工具-生成合并文件】使用python实现2个excel文件根据主键合并生成csv文件

1 小工具说明 1.1 功能说明 一般来说&#xff0c;我们会先有一个老的文件&#xff0c;这个文件内容是定制好相关列的表格&#xff0c;作为每天的报告。 当下一天来的时候&#xff0c;需要根据新的报表文件和昨天的报表文件做一个合并&#xff0c;合并的时候就会出现有些事新增…

信息学奥赛一本通-编程启蒙3330:【例56.1】 和为给定数

3330&#xff1a;【例56.1】 和为给定数 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 625 通过数: 245 【题目描述】 现给出若干个整数&#xff0c;询问其中是否有一对数的和等于给定的数。 【输入】 共三行&#xff1a; 第一行是整数nn(0<n≤100,000)&…

指数分布优化器(EDO)(含MATLAB代码)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

局部放电发生的现象特点以及解决方案

局部放电发生的现象特点&#xff1a;   1、局部放电是局部过热&#xff0c;电器元件和机械元件老化的预兆&#xff1b;   2、局部放电趋势是局放随着时间的上升指数&#xff0c;这是个曲折的过程&#xff0c;某个阶段可能下降&#xff0c;但某个阶段上升&#xff1b;   3…

C# - Opencv应用(1) 之VS下环境配置详解

C# - Opencv应用&#xff08;1&#xff09; 之VS下环境配置详解 有时候&#xff0c;单纯c#做前端时会联合C实现的dll来落地某些功能由于有时候会用C - Opencv实现算法后封装成dll&#xff0c;但是有时候会感觉麻烦&#xff0c;不如直接通过C#直接调用Opencv在此慢慢总结下C# -…

练[极客大挑战 2019]RCE ME

[极客大挑战 2019]RCE ME 文章目录 [极客大挑战 2019]RCE ME掌握知识解题思路关键paylaod 掌握知识 ​ RCE无数字和字母的bypass&#xff0c;取反 异或 递增 解题思路 打开题目链接&#xff0c;发现是代码审计的题目&#xff0c;而且代码比较简单&#xff0c;似乎关键就是RC…

一个很愚蠢的游戏(中)!!!

系列文章目录 c小游戏_睡觉觉觉得的博客-CSDN博客一个很愚蠢的游戏(上)&#xff01;&#xff01;&#xff01;_睡觉觉觉得的博客-CSDN博客 文章目录 系列文章目录前言一、个人名片二、描述三、代码1.代码 总结 前言 无 &#xff08;嘻嘻&#xff09; 一、个人名片 个人主页&a…

[NewStarCTF 2023 公开赛道] week1

最近没什么正式比赛&#xff0c;都是入门赛&#xff0c;有moectf,newstar,SHCTF,0xGame都是漫长的比赛。一周一堆制。 这周newstar第1周结束了&#xff0c;据说py得很厉害&#xff0c;第2周延期了&#xff0c;什么时候开始还不一定&#xff0c;不过第一周已经结束提交了&#…

python --在2x2的子图中绘制三个子图,并使第三个子图居中

python – 在2x2的子图中绘制三个子图&#xff0c;并使第三个子图居中 基于python&#xff0c;绘制一个2x2的子图范围&#xff0c;但是只显示3个子图&#xff0c;并使得第三个子图居中显示’ 思路&#xff1a; 建立一个2x2的子图前两个正常画&#xff0c;其中第三个子图跨越两…

[开源项目推荐]privateGPT使用体验和修改

文章目录 一.跑通简述二.解读ingest.py1.导入库和读取环境变量2.文档加载3.文档处理&#xff08;调用文件加载函数和文本分割函数&#xff09; 三.injest.py效果演示1.main函数解读2.测试 四.修改代码&#xff0c;使之适配多知识库需求1.修改配置文件&#xff1a;constants.py2…

H桥级联型五电平三相逆变器Simulink仿真模型

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

天线基础知识概述

一、天线方向图(一) 图1 天线方向图的辐射能量 辐射能量完全集中在天线方向图的主瓣。这样就不会有副瓣。所有的辐射能量都在天线的半功率波束宽度内。在这些−3dB边界之外,没有能量辐射。在−3dB范围内,能量分布均匀。为了能够对天线进行计算,通常会对计算进行一些简化甚…

MATLAB中syms函数使用

目录 语法 说明 示例 创建符号标量变量 创建符号标量变量的向量 创建符号标量变量矩阵 管理符号标量变量的假设 创建和评估符号函数 syms函数的作用是创建符号标量和函数&#xff0c;以及矩阵变量和函数。 语法 syms var1 ... varN syms var1 ... varN [n1 ... nM] …

VBA_MF系列技术资料1-197

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04属于定…

剑指offer——JZ27 二叉树的镜像 解题思路与具体代码【C++】

一、题目描述与要求 二叉树的镜像_牛客题霸_牛客网 (nowcoder.com) 题目描述 操作给定的二叉树&#xff0c;将其变换为源二叉树的镜像。 数据范围&#xff1a;二叉树的节点数 0≤n≤1000 &#xff0c; 二叉树每个节点的值 0≤val≤1000 要求&#xff1a; 空间复杂度 O(n) …

批量输出生成宗地图斑界址点成果表,支持自动分页,纯FME实现

目录 一、实现效果 二、实现过程 1.图斑转点 2.设置界址点号 3.计算界址点输出Excel的位置 4.计算边长 5.提取每页最后一个界址点 6.设置界址点成果表其他信息 7.输出Excel 三、总结 制作图斑界址点成果表是经常遇到的工作&#xff0c;除了要输出界址点坐标&#xff…

Docker基本操作【一篇学会项目部署】

文章目录 一、Docker简介二、Docker安装三、配置镜像加速四、Docker部署五、Docker基础操作1. 常见命令2. 操作演示3. 数据卷①nginx的html目录挂载②分析匿名数据卷③MySQL的本地目录挂载 4. 自定义镜像①Dockerfile②构建镜像 5. 网络①常见命令②自定义网络 六、DockerCompo…

五种雷达波束模式简介及其应用场景

图1 雷达天线方向图一览 一、铅笔光束——Pencil beam: 方位角和仰角都很窄的光束&#xff08;像铅笔一样细&#xff09;&#xff1b;用于三维雷达&#xff0c;如仪表雷达、天气雷达和防空雷达。 二、扇形波束——Fan beam 方位角非常窄&#xff08;接近1至2&#xff09;&am…