refactor(admin): 重构管理模块VO包结构并新增标签管理功能
- 将分类相关VO移至com.hanserwei.admin.model.vo.category包下,用户相关VO移至user包 - 新增标签管理相关VO,包括AddTagReqVO、DeleteTagReqVO、FindTagPageListReqVO、FindTagPageListRspVO、SearchTagReqVO - 增加AdminTagController,实现标签的增删查和分页查询接口 - 实现AdminTagService及其Impl,完成标签的增删查分页功能 - 新增Tag实体及TagRepository,支持标签数据的持久化及模糊查询 - 优化AdminCategoryServiceImpl分页查询逻辑,提取公共分页查询工具类PageHelper - 修改CategoryRepository继承JpaSpecificationExecutor,支持动态查询 - 修改TokenAuthenticationFilter,限制JWT认证仅校验/admin路径请求 - 修改Category实体删除注解,调整逻辑删除实现 - 新增数据库脚本,创建t_tag标签表及相关索引和触发器 - 更新ResponseCodeEnum,增加TAG_NOT_EXIST和CATEGORY_NOT_EXIST错误码 - 调整.gitignore,忽略.idea下Apifox相关缓存文件
This commit is contained in:
@@ -44,58 +44,64 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
|
||||
// 1. 从请求头中获取 Authorization
|
||||
String header = request.getHeader("Authorization");
|
||||
|
||||
// 2. 校验头格式 (必须以 Bearer 开头)
|
||||
if (header != null && header.startsWith("Bearer ")) {
|
||||
String token = StringUtils.substring(header, 7);
|
||||
log.info("JWT Token: {}", token);
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
try {
|
||||
// 3. 解析 Token (核心步骤)
|
||||
// 注意:JwtTokenHelper.parseToken 方法内部已经处理了 JWT 格式校验和过期校验,
|
||||
// 并将 JJWT 异常转换为了 Spring Security 的 AuthenticationException 抛出。
|
||||
Jws<Claims> claimsJws = jwtTokenHelper.parseToken(token);
|
||||
String requestURI = request.getRequestURI();
|
||||
log.info("Request URI: {}", requestURI);
|
||||
if (requestURI.startsWith("/admin")) {
|
||||
// 2. 校验头格式 (必须以 Bearer 开头)
|
||||
if (header != null && header.startsWith("Bearer ")) {
|
||||
String token = StringUtils.substring(header, 7);
|
||||
log.info("JWT Token: {}", token);
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
try {
|
||||
// 3. 解析 Token (核心步骤)
|
||||
// 注意:JwtTokenHelper.parseToken 方法内部已经处理了 JWT 格式校验和过期校验,
|
||||
// 并将 JJWT 异常转换为了 Spring Security 的 AuthenticationException 抛出。
|
||||
Jws<Claims> claimsJws = jwtTokenHelper.parseToken(token);
|
||||
|
||||
// 4. 获取用户名
|
||||
// JJWT 0.12+ 建议使用 getPayload() 替代 getBody()
|
||||
// 在 Helper 中生成 Token 时使用的是 .subject(username),所以这里取 Subject
|
||||
String username = claimsJws.getPayload().getSubject();
|
||||
// 4. 获取用户名
|
||||
// JJWT 0.12+ 建议使用 getPayload() 替代 getBody()
|
||||
// 在 Helper 中生成 Token 时使用的是 .subject(username),所以这里取 Subject
|
||||
String username = claimsJws.getPayload().getSubject();
|
||||
|
||||
// 5. 组装认证信息 (如果当前上下文没有认证信息)
|
||||
if (StringUtils.isNotBlank(username) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {
|
||||
// 5. 组装认证信息 (如果当前上下文没有认证信息)
|
||||
if (StringUtils.isNotBlank(username) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {
|
||||
|
||||
// 查询数据库获取用户完整信息 (包含权限)
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
// 查询数据库获取用户完整信息 (包含权限)
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
|
||||
// 构建 Spring Security 的认证 Token
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
||||
userDetails,
|
||||
null,
|
||||
userDetails.getAuthorities()
|
||||
);
|
||||
// 构建 Spring Security 的认证 Token
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
||||
userDetails,
|
||||
null,
|
||||
userDetails.getAuthorities()
|
||||
);
|
||||
|
||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
|
||||
// 6. 将认证信息存入 SecurityContext
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
// 6. 将认证信息存入 SecurityContext
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
} catch (AuthenticationException e) {
|
||||
// 7. 异常处理
|
||||
// 捕获 JwtTokenHelper 抛出的 BadCredentialsException 或 CredentialsExpiredException
|
||||
// 如果 Token 存在但是无效/过期,直接交给 EntryPoint 处理响应 (通常返回 401)
|
||||
// 并 return 结束当前过滤器,不再往下执行
|
||||
authenticationEntryPoint.commence(request, response, e);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
// 处理其他未预料到的异常
|
||||
log.error("JWT处理过程中发生未知错误", e);
|
||||
authenticationEntryPoint.commence(request, response, new AuthenticationException("系统内部认证错误") {
|
||||
});
|
||||
return;
|
||||
}
|
||||
} catch (AuthenticationException e) {
|
||||
// 7. 异常处理
|
||||
// 捕获 JwtTokenHelper 抛出的 BadCredentialsException 或 CredentialsExpiredException
|
||||
// 如果 Token 存在但是无效/过期,直接交给 EntryPoint 处理响应 (通常返回 401)
|
||||
// 并 return 结束当前过滤器,不再往下执行
|
||||
authenticationEntryPoint.commence(request, response, e);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
// 处理其他未预料到的异常
|
||||
log.error("JWT处理过程中发生未知错误", e);
|
||||
authenticationEntryPoint.commence(request, response, new AuthenticationException("系统内部认证错误") {
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 8. 放行请求 (如果没有 Token 或者 Token 校验通过,继续执行下一个过滤器)
|
||||
filterChain.doFilter(request, response);
|
||||
// 8. 放行请求 (如果没有 Token 或者 Token 校验通过,继续执行下一个过滤器)
|
||||
filterChain.doFilter(request, response);
|
||||
} else {
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user