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 TAppUserService appUserService; @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不能为空"); } // 查询用户信息 TAppUser appUser = appUserService.getById(appUserId); if (appUser == null) { return AuthResult.failure("用户不存在"); } // 检查用户状态 if (appUser.getStatus() == null || appUser.getStatus() != 1) { return AuthResult.failure("用户已被禁用"); } // 检查用户审核状态 if (appUser.getState() == null || appUser.getState() != 1) { return AuthResult.failure("用户未通过审核"); } // 这里可以添加token验证逻辑 if (token != null && !token.trim().isEmpty()) { // 验证token的有效性 if (!validateToken(appUserId, token)) { return AuthResult.failure("认证令牌无效"); } } return AuthResult.success(appUser); } 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 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; } } }