首次登錄成功後,將用戶名寫入 Cookie(設置有效期),後續訪問自動讀取 Cookie 實現免密登錄。注意:此為教學演示,生產環境嚴禁在 Cookie 存儲明文用戶名/密碼,應使用加密 Token + 數據庫驗證。
login.jsp:登錄表單,POST 提交至 index.jsp。index.jsp:核心邏輯——讀取參數/讀取 Cookie/設置 Cookie/重定向。<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>登錄頁面</title></head>
<body>
<h2>用戶登錄</h2>
<form action="index.jsp" method="post">
用戶名: <input type="text" name="name" required/><br/><br/>
<input type="submit" value="登錄"/>
</form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java"
import="javax.servlet.http.Cookie" %>
<html>
<head><title>歡迎頁面</title></head>
<body>
<%
String name = request.getParameter("name");
// 1. 首次登錄:獲取表單參數,寫入 Cookie
if (name != null && !name.trim().isEmpty()) {
Cookie cookie = new Cookie("autoLoginUser", name.trim());
cookie.setMaxAge(30); // 有效期 30 秒(演示用,實際通常 7-30 天)
cookie.setPath("/"); // 全路徑可見
cookie.setHttpOnly(true); // 防 XSS 竊取(需 Servlet 3.0+)
response.addCookie(cookie);
}
// 2. 非首次訪問:嘗試從 Cookie 讀取
else {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
if ("autoLoginUser".equals(c.getName())) {
name = c.getValue();
break;
}
}
}
}
// 3. 判斷是否登錄成功
if (name != null && !name.trim().isEmpty()) {
out.print("你好, " + name + "! <a href='logout.jsp'>退出登錄</a>");
} else {
// 4. 無 Cookie 或 Cookie 失效:重定向登錄頁
response.sendRedirect("login.jsp");
}
%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
Cookie cookie = new Cookie("autoLoginUser", "");
cookie.setMaxAge(0); // 立即刪除
cookie.setPath("/");
response.addCookie(cookie);
response.sendRedirect("login.jsp");
%>
| 方法/屬性 | 說明 |
|---|---|
new Cookie(name, value) | 創建 Cookie,值不含空格/分號/逗號,建議 URL 編碼 |
setMaxAge(seconds) | >0: 持久化(秒);=0: 立即刪除;<0: 會話級(瀏覽器關閉失效) |
setPath("/") | Cookie 可見路徑,根路徑全站共享 |
setHttpOnly(true) | 禁止 JavaScript 訪問(document.cookie),防 XSS |
setSecure(true) | 僅 HTTPS 傳輸,生產必須啟用 |
request.getCookies() | 返回 Cookie 數組,無則返回 null(非空數組) |
token → userId,設置過期時間。// 登錄成功
String token = UUID.randomUUID().toString().replace("-", "");
redisTemplate.opsForValue().set("autologin:" + token, userId, 30, TimeUnit.DAYS);
Cookie cookie = new Cookie("AUTO_LOGIN_TOKEN", token);
cookie.setMaxAge(30 * 24 * 3600);
cookie.setHttpOnly(true);
cookie.setSecure(true);
cookie.setPath("/");
response.addCookie(cookie);
// 後續請求攔截器
String token = cookieValue(request, "AUTO_LOGIN_TOKEN");
if (token != null) {
String userId = redisTemplate.opsForValue().get("autologin:" + token);
if (userId != null) {
// 刷新過期時間(滑動窗口)
redisTemplate.expire("autologin:" + token, 30, TimeUnit.DAYS);
// 設置當前用戶上下文
SecurityContextHolder.getContext().setAuthentication(new UserAuth(userId));
}
}
Cookie 自動登錄核心流程:登錄寫 Cookie → 訪問讀 Cookie → 登出刪 Cookie。理解 Cookie 生命週期、作用域、安全屬性是 Web 開發基礎。**生產系統務必採用 Token + 服務端存儲 + 簽名驗證 + HTTPS + HttpOnly + SameSite** 多層防護體系。