关于cookie

1:服务器可以向客户端写内容
2:只能是文本内容
3:客户端可以阻止服务器写入
4:只能拿自己webapp写入的东西
5:Cookie分为两种
属于窗口/子窗口(放在内存中的)
属于文本(有生命周期的)
6:在IE浏览器中,一个servlet/jsp设置的cookies能够被同一个路径下面或者子路径下面的servlet/jsp读到(路径 = URL)
(路径 != 真实文件路径)
  但是,子路径下面的cookies不能被父路径下的servlet/jsp读到。
<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,支持分布式扩展
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值