xuhy
2025-11-27 51909b45d3d04b7bf667ba7bb52d7ea6353de3be
ruoyi-applet/src/main/java/com/ruoyi/web/controller/webSocket/WebSocketAuthHandler.java
@@ -1,224 +1,222 @@
package com.ruoyi.web.controller.webSocket;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginUserApplet;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.model.TAppUser;
import com.ruoyi.system.service.TAppUserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Map;
/**
 * WebSocket认证处理器
 * 处理WebSocket连接的用户认证逻辑
 */
@Component
@Slf4j
public class WebSocketAuthHandler {
    @Autowired
    private RedisCache redisCache;
    // 令牌秘钥
    @Value("${token.secret}")
    private String secret;
    /**
     * 验证用户认证信息
     * @param appUserId 用户ID
     * @param token 认证令牌(可选)
     * @return 认证结果
     */
    public AuthResult authenticateUser(String appUserId, String token) {
        try {
            if (appUserId == null || appUserId.trim().isEmpty()) {
                return AuthResult.failure("用户ID不能为空");
            }
            return AuthResult.success();
        } catch (Exception e) {
            log.error("用户认证失败,用户ID: {}, 错误: {}", appUserId, e.getMessage(), e);
            return AuthResult.failure("认证过程中发生错误: " + e.getMessage());
        }
    }
    /**
     * 验证token
     * @param appUserId 用户ID
     * @param token 令牌
     * @return 是否有效
     */
    private boolean validateToken(String appUserId, String token) {
        try {
            if (!StringUtils.hasText(token)) {
                log.debug("用户 {} 未提供token,跳过token验证", appUserId);
                return true; // 如果没有提供token,允许通过(可以根据业务需求调整)
            }
            // 移除Bearer前缀
            if (token.startsWith(Constants.TOKEN_PREFIX)) {
                token = token.replace(Constants.TOKEN_PREFIX, "");
            }
            // 解析JWT token
            Claims claims = parseToken(token);
            if (claims == null) {
                log.warn("用户 {} 的token解析失败", appUserId);
                return false;
            }
            // 从token中获取用户标识
            String uuid = (String) claims.get(Constants.LOGIN_USER_APPLET_KEY);
            if (!StringUtils.hasText(uuid)) {
                log.warn("用户 {} 的token中未找到用户标识", appUserId);
                return false;
            }
            // 从Redis中获取用户登录信息
            String userKey = getTokenKey(uuid);
            LoginUserApplet loginUser = redisCache.getCacheObject(userKey);
            if (loginUser == null) {
                log.warn("用户 {} 的登录信息已过期或不存在", appUserId);
                return false;
            }
            // 验证用户ID是否匹配
            if (!appUserId.equals(loginUser.getUserId())) {
                log.warn("用户 {} 的token与提供的用户ID不匹配", appUserId);
                return false;
            }
            // 验证token是否过期
            long currentTime = System.currentTimeMillis();
            if (loginUser.getExpireTime() != null && loginUser.getExpireTime() < currentTime) {
                log.warn("用户 {} 的token已过期", appUserId);
                return false;
            }
            log.debug("用户 {} 的token验证成功", appUserId);
            return true;
        } catch (Exception e) {
            log.error("验证用户 {} 的token时发生错误: {}", appUserId, e.getMessage(), e);
            return false;
        }
    }
    /**
     * 解析JWT token
     * @param token JWT token
     * @return Claims对象
     */
    private Claims parseToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            log.error("解析token失败: {}", e.getMessage());
            return null;
        }
    }
    /**
     * 获取token在Redis中的key
     * @param uuid 用户唯一标识
     * @return Redis key
     */
    private String getTokenKey(String uuid) {
        return com.ruoyi.common.constant.CacheConstants.LOGIN_TOKEN_KEY + uuid;
    }
    /**
     * 认证结果类
     */
    public static class AuthResult {
        private final boolean success;
        private final String message;
        private final TAppUser appUser;
        private AuthResult(boolean success, String message, TAppUser appUser) {
            this.success = success;
            this.message = message;
            this.appUser = appUser;
        }
        public static AuthResult success(TAppUser appUser) {
            return new AuthResult(true, "认证成功", appUser);
        }
        public static AuthResult failure(String message) {
            return new AuthResult(false, message, null);
        }
        public boolean isSuccess() {
            return success;
        }
        public String getMessage() {
            return message;
        }
        public TAppUser getAppUser() {
            return appUser;
        }
    }
    /**
     * 从认证消息中提取用户信息
     * @param messageObj 消息对象
     * @return 用户认证信息
     */
    public UserAuthInfo extractAuthInfo(Map<String, Object> messageObj) {
        String appUserId = (String) messageObj.get("appUserId");
        String token = (String) messageObj.get("token");
        String deviceId = (String) messageObj.get("deviceId");
        String deviceType = (String) messageObj.get("deviceType");
        return new UserAuthInfo(appUserId, token, deviceId, deviceType);
    }
    /**
     * 用户认证信息类
     */
    public static class UserAuthInfo {
        private final String appUserId;
        private final String token;
        private final String deviceId;
        private final String deviceType;
        public UserAuthInfo(String appUserId, String token, String deviceId, String deviceType) {
            this.appUserId = appUserId;
            this.token = token;
            this.deviceId = deviceId;
            this.deviceType = deviceType;
        }
        public String getAppUserId() {
            return appUserId;
        }
        public String getToken() {
            return token;
        }
        public String getDeviceId() {
            return deviceId;
        }
        public String getDeviceType() {
            return deviceType;
        }
    }
}
//package com.ruoyi.web.controller.webSocket;
//
//import com.ruoyi.common.constant.Constants;
//import com.ruoyi.common.core.domain.model.LoginUserApplet;
//import com.ruoyi.common.core.redis.RedisCache;
//import io.jsonwebtoken.Claims;
//import io.jsonwebtoken.Jwts;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Component;
//import org.springframework.util.StringUtils;
//
//import java.util.Map;
//
///**
// * WebSocket认证处理器
// * 处理WebSocket连接的用户认证逻辑
// */
//@Component
//@Slf4j
//public class WebSocketAuthHandler {
//
//
//    @Autowired
//    private RedisCache redisCache;
//
//    // 令牌秘钥
//    @Value("${token.secret}")
//    private String secret;
//
//    /**
//     * 验证用户认证信息
//     * @param appUserId 用户ID
//     * @param token 认证令牌(可选)
//     * @return 认证结果
//     */
//    public AuthResult authenticateUser(String appUserId, String token) {
//        try {
//            if (appUserId == null || appUserId.trim().isEmpty()) {
//                return AuthResult.failure("用户ID不能为空");
//            }
//
//
//            return AuthResult.success();
//        } catch (Exception e) {
//            log.error("用户认证失败,用户ID: {}, 错误: {}", appUserId, e.getMessage(), e);
//            return AuthResult.failure("认证过程中发生错误: " + e.getMessage());
//        }
//    }
//
//    /**
//     * 验证token
//     * @param appUserId 用户ID
//     * @param token 令牌
//     * @return 是否有效
//     */
//    private boolean validateToken(String appUserId, String token) {
//        try {
//            if (!StringUtils.hasText(token)) {
//                log.debug("用户 {} 未提供token,跳过token验证", appUserId);
//                return true; // 如果没有提供token,允许通过(可以根据业务需求调整)
//            }
//
//            // 移除Bearer前缀
//            if (token.startsWith(Constants.TOKEN_PREFIX)) {
//                token = token.replace(Constants.TOKEN_PREFIX, "");
//            }
//
//            // 解析JWT token
//            Claims claims = parseToken(token);
//            if (claims == null) {
//                log.warn("用户 {} 的token解析失败", appUserId);
//                return false;
//            }
//
//            // 从token中获取用户标识
//            String uuid = (String) claims.get(Constants.LOGIN_USER_APPLET_KEY);
//            if (!StringUtils.hasText(uuid)) {
//                log.warn("用户 {} 的token中未找到用户标识", appUserId);
//                return false;
//            }
//
//            // 从Redis中获取用户登录信息
//            String userKey = getTokenKey(uuid);
//            LoginUserApplet loginUser = redisCache.getCacheObject(userKey);
//
//            if (loginUser == null) {
//                log.warn("用户 {} 的登录信息已过期或不存在", appUserId);
//                return false;
//            }
//
//            // 验证用户ID是否匹配
//            if (!appUserId.equals(loginUser.getUserId())) {
//                log.warn("用户 {} 的token与提供的用户ID不匹配", appUserId);
//                return false;
//            }
//
//            // 验证token是否过期
//            long currentTime = System.currentTimeMillis();
//            if (loginUser.getExpireTime() != null && loginUser.getExpireTime() < currentTime) {
//                log.warn("用户 {} 的token已过期", appUserId);
//                return false;
//            }
//
//            log.debug("用户 {} 的token验证成功", appUserId);
//            return true;
//
//        } catch (Exception e) {
//            log.error("验证用户 {} 的token时发生错误: {}", appUserId, e.getMessage(), e);
//            return false;
//        }
//    }
//
//    /**
//     * 解析JWT token
//     * @param token JWT token
//     * @return Claims对象
//     */
//    private Claims parseToken(String token) {
//        try {
//            return Jwts.parser()
//                    .setSigningKey(secret)
//                    .parseClaimsJws(token)
//                    .getBody();
//        } catch (Exception e) {
//            log.error("解析token失败: {}", e.getMessage());
//            return null;
//        }
//    }
//
//    /**
//     * 获取token在Redis中的key
//     * @param uuid 用户唯一标识
//     * @return Redis key
//     */
//    private String getTokenKey(String uuid) {
//        return com.ruoyi.common.constant.CacheConstants.LOGIN_TOKEN_KEY + uuid;
//    }
//
//    /**
//     * 认证结果类
//     */
//    public static class AuthResult {
//        private final boolean success;
//        private final String message;
////        private final TAppUser appUser;
//
//        private AuthResult(boolean success, String message) {
//            this.success = success;
//            this.message = message;
////            this.appUser = appUser;
//        }
//
////        public static AuthResult success(TAppUser appUser) {
////            return new AuthResult(true, "认证成功", appUser);
////        }
////
////        public static AuthResult failure(String message) {
////            return new AuthResult(false, message, null);
////        }
////
////        public boolean isSuccess() {
////            return success;
////        }
////
////        public String getMessage() {
////            return message;
////        }
////
////        public TAppUser getAppUser() {
////            return appUser;
////        }
//    }
//
//    /**
//     * 从认证消息中提取用户信息
//     * @param messageObj 消息对象
//     * @return 用户认证信息
//     */
//    public UserAuthInfo extractAuthInfo(Map<String, Object> messageObj) {
//        String appUserId = (String) messageObj.get("appUserId");
//        String token = (String) messageObj.get("token");
//        String deviceId = (String) messageObj.get("deviceId");
//        String deviceType = (String) messageObj.get("deviceType");
//
//        return new UserAuthInfo(appUserId, token, deviceId, deviceType);
//    }
//
//    /**
//     * 用户认证信息类
//     */
//    public static class UserAuthInfo {
//        private final String appUserId;
//        private final String token;
//        private final String deviceId;
//        private final String deviceType;
//
//        public UserAuthInfo(String appUserId, String token, String deviceId, String deviceType) {
//            this.appUserId = appUserId;
//            this.token = token;
//            this.deviceId = deviceId;
//            this.deviceType = deviceType;
//        }
//
//        public String getAppUserId() {
//            return appUserId;
//        }
//
//        public String getToken() {
//            return token;
//        }
//
//        public String getDeviceId() {
//            return deviceId;
//        }
//
//        public String getDeviceType() {
//            return deviceType;
//        }
//    }
//}