diff --git a/src/main/java/com/dora/config/WebConfig.java b/src/main/java/com/dora/config/WebConfig.java index 227c407..fc94605 100644 --- a/src/main/java/com/dora/config/WebConfig.java +++ b/src/main/java/com/dora/config/WebConfig.java @@ -116,6 +116,7 @@ public class WebConfig implements WebMvcConfigurer { .order(2); // JWT 认证拦截器(小程序用户) + // 注:/work/{id} 详情页面的可选认证已在拦截器内部通过正则匹配处理 registry.addInterceptor(jwtAuthInterceptor) .addPathPatterns("/**") // 排除不需要认证的接口 @@ -126,8 +127,9 @@ public class WebConfig implements WebMvcConfigurer { "/user/check", "/user/wx-login", "/user/refresh-token", - // 公开接口 - 作品相关(/work/*匹配/work/{id}和/work/list,不匹配/work/{id}/like) - "/work/*", + // 公开接口 - 作品列表和分类 + "/work/list", + "/work/categories", // 分类和Banner "/category/**", "/banner/**", diff --git a/src/main/java/com/dora/interceptor/JwtAuthInterceptor.java b/src/main/java/com/dora/interceptor/JwtAuthInterceptor.java index c440254..f59a14e 100644 --- a/src/main/java/com/dora/interceptor/JwtAuthInterceptor.java +++ b/src/main/java/com/dora/interceptor/JwtAuthInterceptor.java @@ -20,13 +20,24 @@ import org.springframework.web.servlet.HandlerInterceptor; public class JwtAuthInterceptor implements HandlerInterceptor { private final JwtUtil jwtUtil; + + // 公开路径(可选认证:有token则解析,无token也放行) + private static final java.util.regex.Pattern OPTIONAL_AUTH_PATTERN = + java.util.regex.Pattern.compile("^/work/\\d+$"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String requestURI = request.getRequestURI(); + boolean isOptionalAuthPath = OPTIONAL_AUTH_PATTERN.matcher(requestURI).matches(); + // 从请求头获取token String authHeader = request.getHeader("Authorization"); if (authHeader == null || !authHeader.startsWith("Bearer ")) { + // 可选认证路径:无token也放行 + if (isOptionalAuthPath) { + return true; + } sendError(response, HttpServletResponse.SC_UNAUTHORIZED, "未提供认证令牌"); return false; } @@ -36,6 +47,9 @@ public class JwtAuthInterceptor implements HandlerInterceptor { try { // 验证必须是Access Token if (!jwtUtil.isAccessToken(token)) { + if (isOptionalAuthPath) { + return true; // 可选认证路径:无效token也放行 + } sendError(response, HttpServletResponse.SC_UNAUTHORIZED, "无效的令牌类型"); return false; } @@ -54,9 +68,15 @@ public class JwtAuthInterceptor implements HandlerInterceptor { return true; } catch (ExpiredJwtException e) { + if (isOptionalAuthPath) { + return true; // 可选认证路径:过期token也放行 + } sendError(response, HttpServletResponse.SC_UNAUTHORIZED, "令牌已过期"); return false; } catch (JwtException e) { + if (isOptionalAuthPath) { + return true; // 可选认证路径:无效token也放行 + } sendError(response, HttpServletResponse.SC_UNAUTHORIZED, "无效的令牌"); return false; }