Cookie与Session是如何联动的?

简介: Cookie与Session是如何联动的?

一、Cookie是什么?


Cookie是属于报头(header)里面的,详情请参考博客:

https://blog.csdn.net/crazy_xieyi/article/details/126745105


Cookie是HTTP协议中的一个字段,同时也是浏览器在客户端这边保存数据的一种比较古老的方式。Cookie是由服务器产生的,通过HTTP响应的Set-Cookie字段来进行设置,并返回给浏览器。Cookie是在浏览器这边进行储存的,浏览器会根据域名/地址来分别储存Cookie。在浏览器的下次请求中Cookie会被自动添加到请求中,发送给服务器。其中Cookie是以键值对结构的字符串来进行储存的,这里的键值对都是程序员自定义的。        


二、Session是什么?


Session叫做“会话”。因为HTTP协议本身是无状态的,如果对服务器进行两次请求,对于服务器来说是感知不到这两次请求的关联关系的。在实际开发中,要求服务器是需要有状态的,比如:当用户完成登陆之后,后续再访问这个网站的时候,服务器就能知道这个用户的身份信息了(前提是浏览器没有清除缓存)。Session是在服务器端进行储存的,Session类似一个hash表,key就是sessionId。value就是程序员自定义的数据(用户的身份信息.......)。


三、Cookie与Session在网页登录中的典型联动流程


Cookie与Session之间是需要相互配合的。相互配合流程如下:


1667916499527.jpg


在这个场景中,服务器返回的set-cookie里面不一定要放sessionId,其实也可以直接把用户信息序列化通过Set-Cookie返回给浏览器。只是Session是一种常见的做法,这样的做法的好处就是方便实现“注销操作”,在服务器这边直接就把session中对应的键值对删了就行。同时,通过session返回也是可以保护用户的隐私的。


四、Cookie与Session的区别


Cookie 是客户端的机制, Session 是服务器端的机制。

Cookie 和 Session 经常会在一起配合使用 . 但是不是必须配合。 完全可以用 Cookie 来保存一些数据在客户端 . 这些数据不一定是用户身份信息 , 也不一定是sessionId,Session 中的  sessionId 也不需要非得通过 Cookie / Set-Cookie 传递。

HttpServletRequest 类中的相关方法

方法 描述

HttpSession

getSession()

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

Cookie[]

getCookies()

返回一个数组 , 包含客户端发送该请求的所有的 Cookie 对象 . 会自动把Cookie 中的格式解析成键值对


HttpServletResponse 类中的相关方法

方法 描述

void addCookie(Cookie cookie)

把指定的cookie 添加到响应中


HttpSession 类中的相关方法

一个 HttpSession 对象里面包含多个键值对 . 我们可以往 HttpSession 中存任何我们需要的信息:

方法 描述

Object getAttribute(String

name)

该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null

void setAttribute(String

name, Object value)

该方法使用指定的名称绑定一个对象到该 session 会话
boolean isNew() 判定当前是否是新创建出的会话


Cookie 类中的相关方法


每个 Cookie 对象就是一个键值对:

方法 描述
String getName() 该方法返回 cookie 的名称。名称在创建后不能改变。 ( 这个值是 Set-Cooke 字段设置给浏览器的 )
String getValue() 该方法获取与 cookie 关联的值

void setValue(String

newValue)

该方法设置与 cookie 关联的值


HTTP 的 Cooke 字段中存储的实际上是多组键值对 . 每个键值对在 Servlet 中都对应了一个 Cookie

对象。通过 HttpServletRequest.getCookies() 获取到请求中的一系列 Cookie 键值对。通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对。


五、关于Cookie与Session联动的案例分析(实现用户登录)


实现简单的用户登陆逻辑,这个代码中主要是通过 HttpSession 类完成 . 并不需要我们手动操作 Cookie 对象。

1667916693407.jpg

前端代码:

<body>
    <form action="login" method="post">
      用户名:<input type="text" name="username">
      <br>
      密码:<input type="password" name="password">
      <br>
      <input type="submit" value="登录">
    </form>
</body>

服务器代码-IndexServlet


@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //根据当前用户请求中的sesionId,获取到用户信息,并显示到页面上
        resp.setContentType("text/html;charset=utf-8");
        //1.判断当前用户是否已经登录(请求中有没有sessionId,以及sessionId是否合法)
        //如果会话不存在,此处在这里就不能创建了,只能查询,不是登录
        HttpSession httpSession = req.getSession(false);
        if (httpSession == null){
            //没有会话,说明当前用户没有登录,就重定向到登录页面
            resp.sendRedirect("login.html");
            return;
        }
        //2.如果用户已经登录,就可以从HttpSession中拿到用户信息了
        String username = (String)httpSession.getAttribute("username");
        Integer loginCount = (Integer) httpSession.getAttribute("loginCount");
        loginCount = loginCount + 1;
        httpSession.setAttribute("loginCount",loginCount);
        //3.返回一个html页面
        StringBuilder html = new StringBuilder();
        html.append("<div>用户:" + username + "</div>");
        html.append("<div>访问次数:" + loginCount + "</div>");
        resp.getWriter().write(html.toString());
    }
}


服务器代码-LoginServlet

@WebServlet("/login")
public class LoginServlet extends HttpServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        //1.先从请求的body中读取用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //2.判定用户名和密码是否正确(这里测试就直接使用固定用户名和密码了
        if (!"zhangsan".equals(username) || !"1234".equals(password)){
            resp.getWriter().write("用户名或密码不正确!");
            return;
        }
        System.out.println("登录成功!");
        //3.登录成功就创建会话(不存在会话就会创建
        //会话是根据请求中的sessionId来查的,sessionId在Cookie中
        //但是此时是首次登录,此时请求中是没有Cookie的,因为Cookie是服务器返回的
        //此时就会触发“找不到就创建”这样的流程
        //同时这里进行的操作是:先创建出一个HttpSession对象(作为value),然后会自动生成一个
        //随机的字符串,作为sessionId(作为Key),然后自动把key和value插入到hash表中
        //同时把这个生成的sessionId 通过 Set-Cookie 字段返回
        HttpSession httpSession = req.getSession(true);
        //此时可以存入自定义的信息(比如用户身份信息......
        httpSession.setAttribute("username","zhangsan");
        httpSession.setAttribute("loginCount",0);  //记录访问次数
        //4.让页面跳转到主页,使用重定向即可
        resp.sendRedirect("index");
    }
}


其中交互过程如下:(以下会用到Fiddler进行抓包分析

https://blog.csdn.net/crazy_xieyi/article/details/126709702


客户端给服务器的第一次交互,是一个登录请求。

请求:

1667916751016.jpg

这里登录成功后,就创建了一个session 对象,同时生成了一个sessionId。

1667916764428.jpg

响应:

1667916777112.jpg

响应里面就可以看到Set-Cookie这个字段,JSESSIONID=E682780C1B1D7FA633FB998DE0E0E038就是Servlet生成的sessionId,key就是JSESSIONID,value就是后面一串十六进制的数字。


然后正是因为这个Location: index,因为这个重定向,就触发了浏览器与服务器的第二次交互。


第二次交互,是一个访问主页的请求。


请求:

1667916790110.jpg

这里我们可以看到,在第二次的请求中就自动带了Cookie,而且你会发现此时第二次的请求与第一次的响应中的Cookie值是一样的,然后服务器就会根据Cookie里面的sessionId去查找匹配,然后返回对应的页面给浏览器。


响应:

1667916801657.jpg

相关文章
|
10天前
|
存储 前端开发 Java
【SpringMVC】——Cookie和Session机制
获取URL中参数@PathVarible,上传文件@RequestPart,HttpServerlet(getCookies()方法,getAttribute方法,setAttribute方法,)HttpSession(getAttribute方法),@SessionAttribute
|
2月前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
80 4
|
2月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
3月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
222 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
3月前
|
存储 安全 数据安全/隐私保护
Cookie 和 Session 的区别及使用 Session 进行身份验证的方法
【10月更文挑战第12天】总之,Cookie 和 Session 各有特点,在不同的场景中发挥着不同的作用。使用 Session 进行身份验证是常见的做法,通过合理的设计和管理,可以确保用户身份的安全和可靠验证。
41 1
|
4月前
|
存储 缓存 数据处理
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
本文介绍了PHP会话控制及Web常用的预定义变量,包括`$_REQUEST`、`$_SERVER`、`$_COOKIE`和`$_SESSION`的用法和示例。涵盖了cookie的创建、使用、删除以及session的工作原理和使用,并通过图书上传的例子演示了session在实际应用中的使用。
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
|
4月前
|
存储 前端开发 Java
JavaWeb基础7——会话技术Cookie&Session
会话技术、Cookie的发送和获取、存活时间、Session钝化与活化、销毁、用户登录注册“记住我”和“验证码”案例
JavaWeb基础7——会话技术Cookie&Session
|
4月前
|
存储 安全 NoSQL
Cookie、Session、Token 解析
Cookie、Session、Token 解析
80 0
|
5月前
|
存储 JavaScript 前端开发
Cookie 反制策略详解:Cookie加解密原理、Cookie和Session机制、Cookie hook、acw_sc__v2、jsl Cookie调试、重定向Cookie
Cookie 反制策略详解:Cookie加解密原理、Cookie和Session机制、Cookie hook、acw_sc__v2、jsl Cookie调试、重定向Cookie
320 1
|
5月前
|
存储 安全 搜索推荐
【JavaWeb 秘籍】Cookie vs Session:揭秘 Web 会话管理的奥秘与实战指南!
【8月更文挑战第24天】本文以问答形式深入探讨了Web开发中关键的会话管理技术——Cookie与Session。首先解释了两者的基本概念及工作原理,随后对比分析了它们在存储位置、安全性及容量上的差异。接着,通过示例代码详细介绍了如何在JavaWeb环境中实现Cookie与Session的操作,包括创建与读取过程。最后,针对不同应用场景提供了选择使用Cookie或Session的指导建议,并提出了保障二者安全性的措施。阅读本文可帮助开发者更好地理解并应用这两种技术。
90 1