关于cookie

本文详细介绍了Cookie的工作机制,包括其如何在客户端保持HTTP状态信息、如何通过HTTP请求和响应头进行交互,以及Cookie的常见使用方法。同时区分了会话Cookie与持久Cookie的不同,并解释了它们在浏览器中的存储方式。

1.cookie机制采用的是在客户端保持 HTTP 状态信息的方案
2.Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器的一个小文本文件。
3.一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器是都会在HTTP请求头中将这个Cookie回传给WEB服务器。
4.底层的实现原理:WEB服务器通过在HTTP 响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器,浏览器通过在HTTP请求消息中增加Cookie请求头字段码回传给WEB服务器。
5.一个Cookie只能便是一种信息,至少含有一个标识信息的(NAME)和设置值(VALUE)。
6.一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
7.浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
8. Cookie的传送示意图
Cookie的传送示意图

一、cookie的常用方法

    //Cookie的构造方法
    public cookie(String name,String value);
    //设置和得到最大有效时间
    setMaxAge()
    getMaxAge()
    //注意:如果setMaxAge()如果时间是正数,就代表保存数据到硬盘,如果时间设置为0,就代表删除cookie信息,删除cookie信息的时候要保证path一致

    //得到name和value
    getName()
    getValue()
    //设置value
    setValue()
    //可在同一应用服务器内共享方法:设置cookie.setPath("/");
    setPath()

    //发送cookie信息到浏览器
    HttpServeltResponse.addCookie()
    得到所有的cookie信息,获取Cookie返回的是一个数组,只能获取所有的Cookie,并不能获取单个的Cookie
    HttpServletRequest.getCookies()

二、会话Cookie和持久Cookie
如果cookie没有设置最大有效时间,那么cookie中的信息会保存到浏览器的内存中,如果关闭浏览器,那么cookie会消失,此刻的cookie叫做会话cookie
如果设置了最大的有效时间,那么cookie中的信息会保存到硬盘中,如果在有效的时间内都可以访问cookie信息,叫做持久Cookie,超过 有效时间就不能访问了

cookie第一次并不能获取到其中的值:第一次访问并没有Cookie,而是WEB服务器第一次响应后写入一个Cookie,当第二次访问时存在Cookie,就会带着Cookie访问,传递给WEB服务器。
<think>我们来实现一个完整的Spring Boot示例,展示如何使用Cookie和Session进行用户状态管理。 需求:用户访问/login进行登录(模拟),服务器创建会话并将用户信息存入session,同时返回一个包含session ID的Cookie。 当用户访问/profile时,通过Cookie中的session ID获取用户信息。 步骤: 1. 创建Spring Boot项目,添加Spring Web和Spring Session依赖(这里使用内存session,生产环境建议Redis) 2. 实现登录接口,设置Cookie 3. 实现个人资料接口,从Session读取数据 注意:为了简化,我们使用内存Session(默认)并模拟用户登录。 依赖(pom.xml): <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-core</artifactId> </dependency> 代码实现:</think>### Cookie与Session实践示例:用户登录状态管理 以下是一个完整的Spring Boot实现,展示如何通过Cookie传递Session ID并在服务端管理用户状态: ```java import org.springframework.web.bind.annotation.*; import javax.servlet.http.*; import java.util.*; @RestController public class AuthController { // 模拟用户数据库(实际应使用数据库) private static final Map<String, String> USER_DB = Map.of( "admin", "admin123", "user", "password" ); // 登录接口:验证凭证并创建会话 @PostMapping("/login") public ResponseEntity<String> login( @RequestParam String username, @RequestParam String password, HttpServletRequest req, HttpServletResponse res ) { // 1. 验证用户凭证 if (!USER_DB.containsKey(username) || !USER_DB.get(username).equals(password)) { return ResponseEntity.status(401).body("用户名或密码错误"); } // 2. 创建唯一会话ID String sessionId = UUID.randomUUID().toString(); // 3. 在服务端存储Session数据(实际应使用Redis) HttpSession session = req.getSession(true); session.setAttribute("username", username); session.setAttribute("loginTime", new Date()); session.setMaxInactiveInterval(30 * 60); // 30分钟超时 // 4. 设置安全Cookie传递Session ID Cookie sessionCookie = new Cookie("SESSION_ID", sessionId); sessionCookie.setHttpOnly(true); sessionCookie.setSecure(true); // 生产环境应开启HTTPS sessionCookie.setPath("/"); sessionCookie.setMaxAge(30 * 60); // 与Session超时一致 res.addCookie(sessionCookie); return ResponseEntity.ok("登录成功!"); } // 个人资料接口:通过Session获取用户数据 @GetMapping("/profile") public ResponseEntity<String> profile(HttpServletRequest req) { // 1. 获取Session对象(不自动创建新Session) HttpSession session = req.getSession(false); // 2. 验证会话有效性 if (session == null || session.getAttribute("username") == null) { return ResponseEntity.status(401).body("请先登录"); } // 3. 返回个性化数据 String username = (String) session.getAttribute("username"); Date loginTime = (Date) session.getAttribute("loginTime"); return ResponseEntity.ok(String.format( "用户: %s\n登录时间: %tT\n会话ID: %s", username, loginTime, session.getId() )); } // 登出接口:销毁会话 @PostMapping("/logout") public ResponseEntity<String> logout(HttpServletRequest req, HttpServletResponse res) { // 1. 使当前Session失效 HttpSession session = req.getSession(false); if (session != null) { session.invalidate(); } // 2. 清除客户端Cookie Cookie cookie = new Cookie("SESSION_ID", null); cookie.setPath("/"); cookie.setMaxAge(0); // 立即过期 res.addCookie(cookie); return ResponseEntity.ok("已退出登录"); } } ``` ### 关键安全机制说明 1. **会话固定攻击防护** ```java // 登录成功后重置Session ID req.changeSessionId(); ``` 2. **会话劫持防护** ```java // 绑定客户端指纹 String fingerprint = req.getHeader("User-Agent") + "@" + req.getRemoteAddr(); session.setAttribute("client_fingerprint", sha256(fingerprint)); // 每次请求验证指纹 public boolean validateFingerprint(HttpServletRequest req) { String current = req.getHeader("User-Agent") + "@" + req.getRemoteAddr(); String stored = (String) req.getSession().getAttribute("client_fingerprint"); return stored != null && stored.equals(sha256(current)); } ``` 3. **Cookie安全属性强化** ```properties # application.properties配置 server.servlet.session.cookie.http-only=true server.servlet.session.cookie.secure=true server.servlet.session.cookie.same-site=lax ``` ### 测试流程 1. **登录** ```bash curl -X POST http://localhost:8080/login \ -d "username=admin&password=admin123" \ -c cookies.txt ``` 2. **访问个人资料** ```bash curl -b cookies.txt http://localhost:8080/profile # 返回:用户: admin 登录时间: 14:30:25 会话ID: D2E5F7... ``` 3. **登出** ```bash curl -X POST -b cookies.txt http://localhost:8080/logout ``` ### 会话存储优化(Redis集成) ```java // 添加依赖:spring-boot-starter-data-redis @Configuration @EnableRedisHttpSession public class RedisSessionConfig { @Bean public LettuceConnectionFactory connectionFactory() { return new LettuceConnectionFactory(); // 默认连接localhost:6379 } } ``` > 配置后Session自动存储在Redis,支持分布式扩展
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值