Cookie和Session

文章介绍了HTTP协议的无状态特性以及如何通过cookie和session来管理客户端和服务器之间的会话状态。cookie由服务器设置,存储在客户端,用于在后续请求中携带信息。session则在服务器端存储用户信息,通过唯一的sessionid与客户端通信。文中还展示了模拟登录功能的代码示例,涉及LoginServlet和IndexServlet的实现。

HTTP协议自身是属于无状态的协议,意思就是默认情况下HTTP协议的客户端和服务器的上一次通信和下一次通信之间是没有关系的,在实际开发中我们需要知道请求之间的关联关系,例如我们登陆过一个网站,当再次登陆该网站时,服务器就知道已经登陆过该网站了

1.回顾

回顾关于cookie的几个知识点

1.cookie是浏览器提供的,持久化存储数据的机制

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

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

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

4.cookie存储在浏览器所在的硬盘中,浏览器根据域名分别存储,有很多cookie,访问一个网站就按域名存储一个cookie

cookie最典型的应用:表示用户的身份信息.

很多网站多有登录功能

当浏览器再次访问服务器时, 请求中就会有cookie,cookie中带有身份序号,服务器查询到身份序号,就能判断身份信息,避免了重复输入登录信息.没查到就重新输入登录信息.访问其他页面也是相同,如果有cookie,就能访问服务器其他页面,删除cookie后刷新,登陆状态就变了,因为本地存储的身份序号被删除了,再次发送请求时,服务器查询不到身份序号了

cookie过期可能是服务器或客户端删掉了,安全性越要高的网站cookie过期时间越长.

方法
String getName() :该方法返回 cookie 的名称。名称在创建后不能改变。 ( 这个值是 SetCooke 字段设置给浏览器的 )
String getValue() :该方法获取与 cookie 关联的值
void setValue(String newValue) :该方法设置与 cookie 关联的值
HTTP 的cookie字段中存储的实际上是多组键值对. 每个键值对在 Servlet 中都对应了一个cookie对象.
通过 HttpServletRequest.getCookies() 获取到请求中的一系列cookie键值对.
通过 HttpServletResponse.addCookie() 可以向响应中添加新的cookie键值对.

2.Session

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

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

sessionId是由服务器生成的"唯一性字符串",从 session 机制的角度来看, 这个唯一性字符串

称为 "sessionId". 但是站在整个登录流程中看待 , 也可以把这个唯一性字符串称为 "token"(代币象征)
具体流程:用户登陆时,服务器在session中添加一个key-value记录,并且将key通过setCookie返回给
客户端,客户端存储了cookie信息
客户端后续再发请求到服务器的时候,会通过http的header携带cookie信息
服务器收到请求之后,根据根据请求中的sessionid/token 在s ession 信息中获取到对应的用户信息 ,
再决定后续的操作
servlet的session默认是保存在内存中的,服务器重启后session会消失
Cookie与Session的关联与区别
关联:在登陆网站功能中要配合使用
区别:cookie是客户端的存储机制,session是服务器的存储机制
cookie里面可以存储各种键值对,除了sessionid还可以存别的,session是专门保存用户的身份信息的
cookie完全可以单独使用,不搭配session
session也可以不搭配cookie,比如手机app登录服务器,也需要session,但是没有cookie概念,cookie是跟浏览器强相关的
cookie是Http协议中的一部分,但是session则是可以与HTTP无关的,其他协议也能用session

3.模拟登录功能

下来我们写一个代码体验
模拟上述所说的登录功能
先写一个html,提交post请求
需求:当前端提交请求,LoginServlet验证是否信息正确,如果登陆成功,跳转到主页,IndexServlet构建动态页面显示用户的名字
创建两个类:LoginServlet类和IndexServlet类

 点击提交,然后进行抓包

 实现两个类

先编写LoginServlet处理请求

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;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //先使用getParameter获取到username,password的值
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //验证信息是否正确
        //正常用数据库保存,这里写死
        //合法:zhangsan  12345
        if(!username.equals("zhangsan")){
            //失败
            //重定向=>登录页
            System.out.println("用户名错误");
            resp.sendRedirect("login.html");
            return;
        }
        if(!password.equals("12345")){
            //失败
            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);
        //重定向到主页
        resp.sendRedirect("index");

    }
}

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

HttpSession对象也是一个键值对

每个会话中:

key:sessionId value:HttpSession对象

每个HttpSession对象中:

类似

key:"username"value:"zhangsan"

setAttribute,getAttribute来存取键值对,内容是程序员定义

接下来编写生成动态页面代码

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;

@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){
            System.out.println("用户未登录");
            resp.sendRedirect("login.html");
            return;
        }
        String username = (String) session.getAttribute("username");
        //执行到这里,session和post中的是一个对象
        //根据同一个sessionid对应到的对象
        resp.setContentType("text/html;charset = utf8");
        resp.getWriter().write("欢迎回来!" + username);
    }
}

 HttpSession session = req.getSession(false);
        //不会触发会话创建

意思是如果有session,就获取,没有也不创建

getAttribute("username");是获取键的值

重启服务器执行:

这是第一次执行:

抓包结果

请求

响应

注意这里设置了cookie

jsessionid就是sessionid 

Location是接下来要跳转的重定向的位置

注意:我们第二次发起请求了!

 抓包后:

Cookie: JSESSIONID=C21C914A93AC8AD3A546B6F9ED26A274

我们可以发现有个 JSESSIONID,这就是sessionId,值是唯一的数字.第一次的post请求是没有这个字段的!!

 响应结果:

只要这次登陆完成了,后续登录请求都会带上刚才的cookie的值(sessionId) 

<think>嗯,用户想了解CookieSession的概念、区别使用场景。从提供的引用内容来看,需要整理出一个清晰的结构化回答。 首先考虑基础概念部分。根据引用12,Cookie是存储在客户端的小型文本数据,由服务器通过Set-Cookie响应头设置,浏览器后续请求会自动携带。Session则是服务器端存储的用户会话信息,通常通过Session ID关联客户端,这个ID经常存储在Cookie里传递。 关于区别部分,引用1给出了详细对比维度:存储位置(客户端vs服务器)、安全性(Cookie有泄露风险)、存储容量(Cookie约4KB限制)、生命周期(Cookie可设置过期时间,Session依赖会话或超时设置)、性能(Session消耗服务器资源)等。引用3提到经典面试题常考这个区别,特别是HTTP无状态协议下它们的作用(引用4)。 使用场景方面,引用1指出Cookie适合持久化存储低敏感信息如用户偏好,Session适合存储敏感或临时数据如购物车。引用3还用医院挂号案例说明Session ID相当于就诊号,用户信息存在医院系统里。 需要特别注意安全问题。引用13都提到Cookie可能被窃取(XSS攻击)、Session可能被劫持,防护措施包括HttpOnly、Secure标记、定期更换Session ID等。引用4的面试题答案也强调HTTPS传输Session ID的重要性。 考虑在回答中加入具体示例增强理解。引用1给出JS设置CookieFlask使用Session的代码片段,准备在回答中展示基本用法。用户登录流程的交互图(引用3描述的Session创建过程)也需要用文字描述清楚。 最后需要总结两者互补关系:Session依赖Cookie传递ID是常见做法,但Token等其他方式也可行(引用3提到URL重写)。会强调现代Web开发中常结合使用,比如JWT方案其实融合了两者特性。 </think> 以下是CookieSession的核心知识整理,结合技术原理与实际应用场景: --- ### **一、基础概念** 1. **Cookie** - **定义**:服务器发送到用户浏览器并**存储在客户端**的小型文本数据(通常≤4KB)[^1][^2]。 - **工作流程**: ```mermaid graph LR A[服务器响应 Set-Cookie] --> B[浏览器存储Cookie] B --> C[后续请求自动携带Cookie] ``` - **示例代码**(JavaScript设置Cookie): ```javascript document.cookie = "username=John; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/"; ``` 2. **Session** - **定义**:服务器创建的**临时存储空间**(如用户ID、购物车数据),通过唯一Session ID关联客户端[^3]。 - **工作流程**: ```mermaid graph LR A[浏览器首次访问] --> B[服务器生成Session ID] B --> C[通过Cookie/URL传递Session ID] C --> D[服务器根据ID读取会话数据] ``` --- ### **二、核心区别** | **维度** | **Cookie** | **Session** | |----------------|-------------------------------------|----------------------------------| | 存储位置 | 客户端浏览器 | 服务器内存/数据库 | | 安全性 | 较低(可能被XSS窃取) | 较高(敏感信息不暴露给客户端) | | 存储容量 | ≤4KB(不同浏览器有差异) | 仅受服务器资源限制 | | 生命周期 | 可设长期有效(如`expires`属性) | 会话结束或超时(通常20-30分钟) | | 性能影响 | 无服务器负担 | 占用服务器资源 | | 数据传输 | 每次HTTP请求自动携带 | 仅传递Session ID | --- ### **三、使用场景** 1. **Cookie适用场景** - 记住登录状态(如`remember me`功能) - 保存用户个性化设置(语言/主题) - 跟踪用户行为(匿名数据分析)[^4] 2. **Session适用场景** - 存储敏感数据(银行卡号、地址) - 购物车信息临时存储 - 多步骤表单流程(如注册流程)[^1][^3] --- ### **四、安全实践** | **风险** | **防护措施** | |------------------|---------------------------------------| | Cookie劫持 | 添加`HttpOnly``Secure`属性 | | Session固定攻击 | 登录后重置Session ID | | CSRF攻击 | 同步使用CSRF Token | | 数据泄露 | Session数据加密存储(如AES-256) | > ✅ **最佳实践**:敏感操作(如支付)采用`Session + HTTPS`,非敏感数据用Cookie[^3]。 --- ### **五、经典面试题解析** 1. **Q: 如何解决分布式系统的Session共享?** - **A**:使用集中存储方案(Redis集群),避免服务器本地存储导致的会话丢失。 2. **Q: 禁用Cookie后如何使用Session?** - **A**:通过URL重写传递Session ID(如`/path;jsessionid=xxx`),但需注意URL暴露风险[^1]。 3. **Q: 为什么Session需要Cookie配合?** - **A**:HTTP协议无状态,Session ID需通过Cookie(或URL)在请求间传递以维持会话[^4]。 --- ### **六、总结** - **协作关系**:Session依赖Cookie传递ID是常见模式,但非唯一方案(如Token认证)。 - **趋势**:现代Web应用趋向**JWT(JSON Web Token)** 替代传统Session,实现无状态认证。 - **设计原则**: > 安全性要求高 → 用Session; > 跨会话持久化 → 用Cookie。 ---
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YoLo♪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值