From bbe5b6ccab777ba3754181038dc3fe3be6fc83e1 Mon Sep 17 00:00:00 2001 From: luke Date: Thu, 5 Jun 2025 23:52:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=C3=A6=C2=B0=E8=AE=BE?= =?UTF-8?q?=E7=BD=AEcookie=E8=AE=BE=E7=BD=AE=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 6 +-- .../parser/application/filter/AuthFilter.java | 4 +- .../infrastructure/config/ConstantConfig.java | 4 ++ .../infrastructure/config/DynamicConfig.java | 15 +++++++ ...ginController.java => UserController.java} | 45 ++++++++++++++++--- 5 files changed, 62 insertions(+), 12 deletions(-) rename src/main/java/com/doc/parser/infrastructure/north/controller/{LoginController.java => UserController.java} (62%) diff --git a/Readme.md b/Readme.md index 3e22b60..c3ee5e3 100644 --- a/Readme.md +++ b/Readme.md @@ -1,9 +1,9 @@ 修订记录 -| 版本 | 时间 | 修订人 | 改动点 | -| :--: |:----------:|:-------:|:-------------------:| +| 版本 | 时间 | 修订人 | 改动点 | +|:-----:|:----------:|:-------:|:-------------------:| | 1.0.0 | 2025-06-05 | Luke.Ye | 添加修订记录(新增token校验接口) | -| | | | | +| 1.0.1 | 2025-06-06 | Luke.Ye | 重构登录Token校验逻辑, | diff --git a/src/main/java/com/doc/parser/application/filter/AuthFilter.java b/src/main/java/com/doc/parser/application/filter/AuthFilter.java index 5a6fea1..33e48c5 100644 --- a/src/main/java/com/doc/parser/application/filter/AuthFilter.java +++ b/src/main/java/com/doc/parser/application/filter/AuthFilter.java @@ -1,6 +1,6 @@ package com.doc.parser.application.filter; -import com.doc.parser.infrastructure.north.controller.LoginController; +import com.doc.parser.infrastructure.north.controller.UserController; import org.springframework.stereotype.Component; import javax.servlet.*; @@ -27,7 +27,7 @@ public class AuthFilter implements Filter { // 需要鉴权的路径前缀 if (path.startsWith("/search")) { String token = request.getHeader("Authorization"); - if (!LoginController.isValidToken(token)) { + if (!UserController.isValidToken(token)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().write("Invalid or expired token"); return; diff --git a/src/main/java/com/doc/parser/infrastructure/config/ConstantConfig.java b/src/main/java/com/doc/parser/infrastructure/config/ConstantConfig.java index 1f6fc6f..f225cbe 100644 --- a/src/main/java/com/doc/parser/infrastructure/config/ConstantConfig.java +++ b/src/main/java/com/doc/parser/infrastructure/config/ConstantConfig.java @@ -6,4 +6,8 @@ package com.doc.parser.infrastructure.config; */ public class ConstantConfig { + /** + * cookie对应的key + */ + public static final String COOKIE_KEY = "auth_token"; } diff --git a/src/main/java/com/doc/parser/infrastructure/config/DynamicConfig.java b/src/main/java/com/doc/parser/infrastructure/config/DynamicConfig.java index 2e6ac56..2e8b310 100644 --- a/src/main/java/com/doc/parser/infrastructure/config/DynamicConfig.java +++ b/src/main/java/com/doc/parser/infrastructure/config/DynamicConfig.java @@ -15,9 +15,16 @@ public class DynamicConfig { @Value("${micro.saas.doc.parser.recordMsgBody:Y}") private String recordMsgBody; + @Value("${cookie.domain.name:wisdompulse.cn}") + private String cookieDomainName; + @Value("${import.schedule.cron:0 0 * * * *}") private String importScheduleCron; + // token失效时间,默认24小时 + @Value("${token.expire.time:86400000}") + private long tokenExpireTime; + public String getRecordMsgBody() { return recordMsgBody; } @@ -25,4 +32,12 @@ public class DynamicConfig { public String getImportScheduleCron() { return importScheduleCron; } + + public String getCookieDomainName() { + return cookieDomainName; + } + + public long getTokenExpireTime() { + return tokenExpireTime; + } } diff --git a/src/main/java/com/doc/parser/infrastructure/north/controller/LoginController.java b/src/main/java/com/doc/parser/infrastructure/north/controller/UserController.java similarity index 62% rename from src/main/java/com/doc/parser/infrastructure/north/controller/LoginController.java rename to src/main/java/com/doc/parser/infrastructure/north/controller/UserController.java index 4dbdb14..e76b071 100644 --- a/src/main/java/com/doc/parser/infrastructure/north/controller/LoginController.java +++ b/src/main/java/com/doc/parser/infrastructure/north/controller/UserController.java @@ -1,8 +1,13 @@ package com.doc.parser.infrastructure.north.controller; +import cn.hutool.extra.spring.SpringUtil; +import com.doc.parser.infrastructure.config.ConstantConfig; +import com.doc.parser.infrastructure.config.DynamicConfig; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -13,7 +18,10 @@ import java.util.concurrent.ConcurrentHashMap; */ @RestController @RequestMapping("/api/v1/user") -public class LoginController { +public class UserController { + + @Autowired + private DynamicConfig dynamicConfig; private static final Map USER_DB = Map.of( "admin", "Admin@654321", @@ -26,8 +34,6 @@ public class LoginController { // token -> username private static final Map userMap = new ConcurrentHashMap<>(); - private static final long TOKEN_EXPIRE_MS = 24 * 60 * 60 * 1000L; // 24 小时 - @PostMapping("/login") public ResponseEntity login(@RequestBody Map body, HttpServletResponse response) { String username = body.getOrDefault("username", "").trim(); @@ -41,10 +47,11 @@ public class LoginController { tokenStore.put(token, System.currentTimeMillis()); userMap.put(token, username); - javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie("auth_token", token); + Cookie cookie = new Cookie( ConstantConfig.COOKIE_KEY, token); cookie.setPath("/"); - cookie.setHttpOnly(false); // 建议生产环境为 true,这里为兼容前端 JS 读写可设为 false - cookie.setMaxAge((int)(TOKEN_EXPIRE_MS / 1000)); + cookie.setDomain(dynamicConfig.getCookieDomainName()); + cookie.setHttpOnly(true); // 建议生产环境为 true,这里为兼容前端 JS 读写可设为 false + cookie.setMaxAge((int)(dynamicConfig.getTokenExpireTime() / 1000)); response.addCookie(cookie); return ResponseEntity.ok(Map.of( @@ -53,6 +60,29 @@ public class LoginController { )); } + @PostMapping("/logout") + public ResponseEntity logout( + @CookieValue(value = ConstantConfig.COOKIE_KEY, required = false) String cookieToken, + @RequestHeader(value = "Authorization", required = false) String headerToken, + HttpServletResponse response + ) { + String token = headerToken != null ? headerToken : cookieToken; + if (token != null && tokenStore.containsKey(token)) { + tokenStore.remove(token); + userMap.remove(token); + } + + // 删除 Cookie + Cookie cookie = new Cookie( ConstantConfig.COOKIE_KEY, ""); + cookie.setPath("/"); + cookie.setDomain(dynamicConfig.getCookieDomainName()); + cookie.setMaxAge(0); // 立即失效 + cookie.setHttpOnly(true); + response.addCookie(cookie); + + return ResponseEntity.ok(Map.of("msg", "已登出")); + } + @GetMapping("/check") public ResponseEntity check( @@ -77,7 +107,8 @@ public class LoginController { if (token == null || !tokenStore.containsKey(token)) return false; long loginAt = tokenStore.get(token); long now = System.currentTimeMillis(); - if (now - loginAt > TOKEN_EXPIRE_MS) { + long expireMs = SpringUtil.getBean(DynamicConfig.class).getTokenExpireTime(); + if (now - loginAt > expireMs) { tokenStore.remove(token); userMap.remove(token); return false;