lrj
8 小时以前 ae3349d2ff53767b5bc9cb30e1bf7e15f9e814ee
backend/src/main/java/com/rongyichuang/auth/filter/JwtAuthenticationFilter.java
@@ -12,6 +12,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
@@ -35,35 +36,88 @@
    @Autowired
    private UserRepository userRepository;
    /**
     * 判断是否应该跳过JWT认证
     */
    private boolean shouldSkipAuthentication(String requestURI) {
        // 这些路径不需要JWT认证(已去掉context path)
        String[] skipPaths = {
            "/auth/",
            "/actuator/",
            "/test/",
            "/cleanup/",
            "/upload/",
            "/graphql",
            "/graphiql"
        };
        for (String path : skipPaths) {
            if (requestURI.startsWith(path)) {
                return true;
            }
        }
        return false;
    }
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
                                  FilterChain filterChain) throws ServletException, IOException {
                                    FilterChain filterChain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        String contextPath = request.getContextPath();
        // 去掉context path,与Spring Security的行为保持一致
        String pathWithoutContext = requestURI;
        if (contextPath != null && !contextPath.isEmpty() && requestURI.startsWith(contextPath)) {
            pathWithoutContext = requestURI.substring(contextPath.length());
        }
        System.out.println("=== JWT过滤器被调用 === 原始URI: " + requestURI + ", 去掉context path后: " + pathWithoutContext);
        logger.debug("JWT过滤器开始处理请求: {}", pathWithoutContext);
        // 跳过不需要认证的路径
        if (shouldSkipAuthentication(pathWithoutContext)) {
            logger.debug("跳过JWT认证,路径: {}", pathWithoutContext);
            filterChain.doFilter(request, response);
            return;
        }
        
        String authHeader = request.getHeader("Authorization");
        String token = null;
        Long userId = null;
        logger.debug("Authorization头: {}", authHeader);
        // 从请求头中提取JWT token
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            token = authHeader.substring(7);
            logger.debug("提取到JWT token: {}", token.substring(0, Math.min(20, token.length())) + "...");
            try {
                userId = jwtUtil.getUserIdFromToken(token);
                logger.debug("从token中解析到用户ID: {}", userId);
            } catch (Exception e) {
                logger.debug("JWT token解析失败: {}", e.getMessage());
                logger.error("JWT token解析失败: {}", e.getMessage(), e);
            }
        } else {
            logger.debug("没有找到Authorization头或格式不正确");
        }
        // 如果token有效且当前没有认证信息
        if (userId != null && SecurityContextHolder.getContext().getAuthentication() == null) {
        // 如果token有效且当前是匿名或无认证,则进行认证
        Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
        boolean isAnonymous = (existingAuth == null) || ("anonymousUser".equals(String.valueOf(existingAuth.getPrincipal())));
        if (userId != null && isAnonymous) {
            logger.debug("开始验证token有效性");
            
            // 验证token是否有效
            if (jwtUtil.validateToken(token)) {
                logger.debug("Token验证成功,查找用户信息");
                
                // 查找用户信息
                Optional<User> userOpt = userRepository.findById(userId);
                if (userOpt.isPresent()) {
                    User user = userOpt.get();
                    logger.debug("找到用户: userId={}, phone={}", user.getId(), user.getPhone());
                    
                    // 创建认证对象
                    UsernamePasswordAuthenticationToken authToken = 
@@ -76,9 +130,17 @@
                    authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authToken);
                    
                    logger.debug("用户认证成功: userId={}, phone={}", user.getId(), user.getPhone());
                    logger.info("用户认证成功: userId={}, phone={}", user.getId(), user.getPhone());
                } else {
                    logger.warn("用户不存在: userId={}", userId);
                }
            } else {
                logger.warn("Token验证失败");
            }
        } else if (userId == null) {
            logger.debug("没有解析到用户ID");
        } else {
            logger.debug("已存在非匿名认证信息,跳过JWT认证");
        }
        filterChain.doFilter(request, response);