杰瑞科技汇

Java设置cookie时间怎么设置?

我将为你详细解释在两种最主流的 Java Web 开发场景中如何设置 Cookie 时间:

Java设置cookie时间怎么设置?-图1
(图片来源网络,侵删)
  1. 原生 Servlet API (适用于任何 Java Web 应用,如 Tomcat, Jetty)
  2. Spring Boot (目前最流行的 Java 框架)

核心概念:Cookie 的有效期类型

在设置时间之前,需要理解 Cookie 有两种主要的有效期类型:

  1. 会话 Cookie (Session Cookie)

    • 特点:没有设置 maxAge 属性,它的生命周期与用户的浏览器会话(Session)绑定。
    • 行为:当用户关闭浏览器时,这个 Cookie 会被自动删除,它不会存储在用户的硬盘上,而是保存在内存中。
    • 设置方式:在 Java 代码中,当你创建 Cookie 对象后,不调用 setMaxAge() 方法,或者调用 setMaxAge(-1),它就会成为会话 Cookie。
  2. 持久化 Cookie (Persistent Cookie)

    • 特点:通过设置 maxAge 属性来指定其存活时间(以秒为单位)。
    • 行为:即使浏览器关闭,只要 Cookie 没有过期,它就会一直存储在用户的硬盘上,下次用户打开浏览器时,Cookie 仍然会随请求发送到服务器。
    • 设置方式:在 Java 代码中,调用 cookie.setMaxAge(seconds)

使用原生 Servlet API

这是最基础的方式,理解了它,有助于你理解 Cookie 的工作原理。

Java设置cookie时间怎么设置?-图2
(图片来源网络,侵删)

关键方法:cookie.setMaxAge(int seconds)

  • 参数 seconds
    • 正数:指定 Cookie 存活的时间(秒)。60 * 60 * 24 * 7 表示一周。
    • 零 (0):立即删除该 Cookie,这通常用于注销登录或清除特定偏好设置。
    • 负数 (-1):表示这是一个会话 Cookie,将在浏览器关闭时被删除,这是默认行为。

示例代码

假设你有一个 Servlet,需要在用户登录后设置一个名为 userToken 的 Cookie,有效期为一周。

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 模拟登录成功
        String username = request.getParameter("username");
        // ... 验证逻辑 ...
        // 2. 创建 Cookie 对象
        Cookie userTokenCookie = new Cookie("userToken", "some_unique_token_string_" + username);
        // 3. 设置 Cookie 的有效期为一周 (单位:秒)
        // 一周 = 7天 * 24小时 * 60分钟 * 60秒
        int oneWeekInSeconds = 7 * 24 * 60 * 60;
        userTokenCookie.setMaxAge(oneWeekInSeconds);
        // 4. (可选但推荐) 设置 Cookie 的路径
        // 这表示只有访问 "/app" 路径及其子路径时,浏览器才会携带这个 Cookie
        // 如果不设置,默认是当前 Servlet 的路径,可能导致在某些页面下 Cookie 不会被发送
        userTokenCookie.setPath("/");
        // 5. 将 Cookie 添加到 HTTP 响应中
        response.addCookie(userTokenCookie);
        // 6. 重定向到主页
        response.sendRedirect("/home.jsp");
    }
}

如何从客户端读取 Cookie?

// 在另一个 Servlet 或 JSP 页面中
Cookie[] cookies = request.getCookies();
if (cookies != null) {
    for (Cookie cookie : cookies) {
        if ("userToken".equals(cookie.getName())) {
            String token = cookie.getValue();
            // 使用这个 token 进行后续操作...
            System.out.println("Found user token: " + token);
            break; // 找到后就可以退出了
        }
    }
}

使用 Spring Boot

Spring Boot 对 Servlet API 进行了封装,提供了更简洁、更强大的方式来操作 Cookie。

使用 HttpServletResponse (与原生 Servlet 类似)

在 Controller 方法中,你可以直接注入 HttpServletResponse,然后使用它的 addCookie 方法,底层仍然是创建 Cookie 对象。

import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
    @PostMapping("/login")
    public String login(@RequestParam String username, HttpServletResponse response) {
        // 1. 创建 Spring 封装的 Cookie 对象 (org.springframework.web.server.ServerWebExchange 下的,但通常用 javax.servlet 的)
        // 为了清晰,我们直接使用 javax.servlet 的 Cookie
        Cookie userTokenCookie = new Cookie("userToken", "spring_boot_token_" + username);
        // 2. 设置有效期 (一周)
        userTokenCookie.setMaxAge(7 * 24 * 60 * 60);
        // 3. 设置路径
        userTokenCookie.setPath("/");
        // 4. 添加到响应
        response.addCookie(userTokenCookie);
        return "Login successful! Cookie has been set.";
    }
    @PostMapping("/logout")
    public String logout(HttpServletResponse response) {
        // 1. 创建一个同名但立即过期的 Cookie 来删除它
        Cookie deleteCookie = new Cookie("userToken", null);
        deleteCookie.setMaxAge(0); // 设置为 0,立即删除
        deleteCookie.setPath("/");
        // 2. 添加到响应
        response.addCookie(deleteCookie);
        return "Logged out successfully! Cookie has been removed.";
    }
}

使用 ResponseCookie (Spring 5 推荐的方式)

ResponseCookie 是 Spring 提供的一个更现代化、功能更丰富的 Cookie 类,它构建器模式,链式调用非常方便,并且能更好地处理编码、安全属性等。

import org.springframework.http.ResponseCookie;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/api/auth")
public class AuthControllerWithResponseCookie {
    @PostMapping("/login-modern")
    public String loginModern(@RequestParam String username, HttpServletResponse response) {
        // 使用 ResponseCookie.Builder 来构建 Cookie
        ResponseCookie cookie = ResponseCookie.from("userToken", "modern_token_" + username)
                .path("/")                 // 设置路径
                .maxAge(7 * 24 * 60 * 60) // 设置有效期 (一周)
                .httpOnly(true)           // 防止 XSS 攻击,禁止 JavaScript 访问
                .secure(true)             // 仅在 HTTPS 连接下发送,增强安全性
                .sameSite("Lax")          // 控制跨站请求,防止 CSRF 攻击
                .build();
        // 将 Cookie 添加到响应头中
        response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
        return "Login successful! Modern cookie has been set.";
    }
}

ResponseCookie 的优势:

  • 链式调用:代码更清晰、易读。
  • 安全性:可以方便地设置 HttpOnlySecureSameSite 等重要的安全属性。
  • 编码处理:能更好地处理 Cookie 值中的特殊字符。

总结与最佳实践

特性 原生 Cookie Spring ResponseCookie 备注
易用性 基础,需要单独设置每个属性 ,构建器模式,链式调用 ResponseCookie 更现代化
安全性 需要手动设置 HttpOnly, Secure 内置支持,可轻松设置 强烈推荐使用 HttpOnlySecure
适用场景 任何 Java Web 环境 Spring 5+ 项目 在 Spring 项目中优先使用 ResponseCookie
删除 Cookie setMaxAge(0) maxAge(0) 两者方式一致

最佳实践建议:

  1. 明确有效期:根据业务需求明确你需要的是会话 Cookie 还是持久化 Cookie。
  2. 设置合理的路径:始终使用 setPath("/") 或一个更具体的路径,避免 Cookie 被不必要地发送,提高性能和安全性。
  3. 安全性第一
    • HttpOnly:Cookie 包含敏感信息(如认证令牌),必须设置为 true,以防止跨站脚本攻击 窃取 Cookie。
    • Secure:在生产环境中,强烈建议设置为 true,确保 Cookie 只通过 HTTPS 连接传输。
    • SameSite:设置为 LaxStrict 可以有效防御 CSRF(跨站请求伪造)攻击。Lax 是一个比较平衡的选择。
  4. 在 Spring 中使用 ResponseCookie:如果你在使用 Spring Boot,请优先考虑使用 ResponseCookie,它能让你更安全、更优雅地管理 Cookie。
分享:
扫描分享到社交APP
上一篇
下一篇