会话 (COOKIE与SESSION)
Cookie
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
@RestController
public class DataController {
// 设置cookie
@GetMapping("/set-cookie")
public String getInfo() {
// 创建 Cookie
Cookie cookie = new Cookie("user_token", "123456");
// 设置有效期(秒),-1 表示浏览器关闭后失效,0 表示立即删除
cookie.setMaxAge(7 * 24 * 60 * 60); // 7天
// 设置路径(默认为当前接口路径,设为 "/" 表示全站有效)
cookie.setPath("/");
// 可选:设置域名(如 .example.com 允许子域名共享)
// cookie.setDomain(".example.com");
// 可选:启用 HTTPS 安全传输
// cookie.setSecure(true);
// 可选:禁止 JavaScript 访问(防 XSS)
cookie.setHttpOnly(true);
// 添加 Cookie 到响应
response.addCookie(cookie);
return "Cookie 已设置";
}
// 删除cookie
@GetMapping("/delete-cookie")
public String deleteCookie(HttpServletResponse response) {
Cookie cookie = new Cookie("user_token", null);
cookie.setMaxAge(0); // 立即失效
cookie.setPath("/"); // 必须与设置时的路径一致
response.addCookie(cookie);
return "Cookie 已删除";
}
// 读取cookie
@GetMapping("/read-cookie")
public String readCookie(@CookieValue(name = "user_token", defaultValue = "unknown") String token) {
return "Cookie 值: " + token;
}
// 遍历所有 Cookie
@GetMapping("/read-all-cookies")
public String readAllCookies(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies == null) {
return "无 Cookie";
}
StringBuilder sb = new StringBuilder();
for (Cookie cookie : cookies) {
sb.append(cookie.getName()).append(": ").append(cookie.getValue()).append("<br>");
}
return sb.toString();
}
}
// Spring Boot 2.4+ 支持通过配置文件设置默认 Cookie 属性
# application.properties
# 设置所有 Cookie 的 SameSite 属性(Strict/Lax/None)
server.servlet.session.cookie.same-site=lax
# 启用 Secure(仅 HTTPS)
server.servlet.session.cookie.secure=true
# 设置 HttpOnly
server.servlet.session.cookie.http-only=true
SESSION
快速使用 Session
直接通过 HttpServletRequest 存取 Session 数据
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@RestController
public class SessionController {
// 写入 Session
@GetMapping("/set-session")
public String setSession(HttpServletRequest request) {
HttpSession session = request.getSession(); // 获取或创建 Session
session.setAttribute("user", "Alice");
return "Session 已设置";
}
// 读取 Session
@GetMapping("/get-session")
public String getSession(HttpServletRequest request) {
HttpSession session = request.getSession(false); // 不创建新 Session
if (session != null) {
return "用户名: " + session.getAttribute("user");
}
return "Session 不存在";
}
// 删除 Session
@GetMapping("/invalidate-session")
public String invalidateSession(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate(); // 销毁 Session
}
return "Session 已销毁";
}
}
配置 Session 超时时间
在 application.properties 中设置(单位:秒)
# 设置 Session 超时时间(默认 30 分钟)
server.servlet.session.timeout=1800
# 配置 Session Cookie 属性
server.servlet.session.cookie.name=MY_SESSION
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
server.servlet.session.cookie.same-site=lax
使用 Spring Session 持久化
将会话存储到外部系统(如 Redis、数据库),实现分布式共享。
(1) 存储到 Redis
步骤 1:添加依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
步骤 2:配置 Redis 连接
# application.properties
spring.redis.host=localhost
spring.redis.port=6379
步骤 3:启用 Redis Session
@EnableRedisHttpSession // 添加在启动类或配置类上
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4. 通过注解简化操作
使用 @SessionAttributes
和 @SessionAttribute
注解管理 Session 数据。
(1) 类级别声明 Session 属性
@Controller
@SessionAttributes("user") // 声明此控制器会将 "user" 存入 Session
public class UserController {
@GetMapping("/login")
public String login(Model model) {
model.addAttribute("user", "Alice"); // 自动存入 Session
return "redirect:/dashboard";
}
}
(2) 方法参数读取 Session
@GetMapping("/dashboard")
public String dashboard(@SessionAttribute(name = "user", required = false) String user) {
if (user == null) {
return "redirect:/login";
}
return "欢迎," + user;
}
5. 安全性建议
- Session 固定攻击防护:
在用户登录成功后调用session.changeSessionId()
重置 Session ID。 - 敏感数据加密:
避免在 Session 中存储敏感信息(如密码),或使用加密存储。 - 结合 Spring Security:
使用 Spring Security 自动管理 Session 安全性(如并发控制、过期处理)。
6. 验证 Session 存储
若使用 Redis,检查 Redis 中是否生成 Session 键:
$ redis-cli
127.0.0.1:6379> KEYS "spring:session:*"
1) "spring:session:sessions:4e9d5b1a-3e4f-4a7c-bb2d-6d8e3f5a1b2c"
总结
| 操作 | 代码示例 |
|——————–|——————————————|
| 写入 Session | session.setAttribute("key", value)
|
| 读取 Session | session.getAttribute("key")
|
| 销毁 Session | session.invalidate()
|
| 分布式 Session | @EnableRedisHttpSession
+ Redis 配置 |
| 超时配置 | server.servlet.session.timeout=1800
|
Session 适用于短期用户状态管理(如登录态),结合 Spring Security 或 Redis 可满足复杂场景需求。
推荐文章: