fix: JT808修改-若NONE跳过鉴权
All checks were successful
aiot-platform CI/CD / build-and-deploy (push) Successful in 7m22s
All checks were successful
aiot-platform CI/CD / build-and-deploy (push) Successful in 7m22s
This commit is contained in:
@@ -7,6 +7,7 @@ import com.viewshanghai.framework.common.pojo.CommonResult;
|
||||
import com.viewshanghai.module.iot.core.biz.IotDeviceCommonApi;
|
||||
import com.viewshanghai.module.iot.core.biz.dto.IotDeviceGetReqDTO;
|
||||
import com.viewshanghai.module.iot.core.biz.dto.IotDeviceRespDTO;
|
||||
import com.viewshanghai.module.iot.core.enums.IotAuthTypeEnum;
|
||||
import com.viewshanghai.module.iot.core.mq.message.IotDeviceMessage;
|
||||
import com.viewshanghai.module.iot.gateway.codec.jt808.IotJt808DeviceMessageCodec;
|
||||
import com.viewshanghai.module.iot.gateway.service.device.message.IotDeviceMessageService;
|
||||
@@ -245,22 +246,30 @@ public class Jt808ProtocolHandler extends AbstractProtocolHandler {
|
||||
return AuthResult.failure("设备不存在");
|
||||
}
|
||||
|
||||
// 3. 从 Redis 获取鉴权码
|
||||
// 3. 从 Redis 获取鉴权码(优先使用注册时缓存的鉴权码)
|
||||
String redisKey = String.format(JT808_AUTH_TOKEN, terminalPhone);
|
||||
String cachedAuthToken = stringRedisTemplate.opsForValue().get(redisKey);
|
||||
|
||||
if (StrUtil.isBlank(cachedAuthToken)) {
|
||||
log.warn("[handleAuth][未找到鉴权码缓存,终端手机号: {},可能未注册或缓存已过期]", terminalPhone);
|
||||
sendCommonResp(socket, terminalPhone, flowId, 0x0102, (byte) 1, codecType, message.getRequestId());
|
||||
return AuthResult.failure("未找到鉴权码,请先注册");
|
||||
boolean authSuccess = false;
|
||||
|
||||
if (StrUtil.isNotBlank(cachedAuthToken)) {
|
||||
// 3.1 如果找到缓存,验证鉴权码是否匹配
|
||||
if (authCode.equals(cachedAuthToken)) {
|
||||
authSuccess = true;
|
||||
log.debug("[handleAuth][使用缓存的鉴权码验证成功,终端手机号: {}]", terminalPhone);
|
||||
} else {
|
||||
log.warn("[handleAuth][缓存的鉴权码验证失败,终端手机号: {}, 期望: {}, 实际: {}]",
|
||||
terminalPhone, cachedAuthToken, authCode);
|
||||
}
|
||||
} else {
|
||||
// 3.2 如果未找到缓存,尝试直接验证(支持跳过注册步骤)
|
||||
log.info("[handleAuth][未找到鉴权码缓存,尝试直接验证,终端手机号: {}]", terminalPhone);
|
||||
authSuccess = validateAuthCodeDirectly(device, authCode, terminalPhone);
|
||||
}
|
||||
|
||||
// 验证鉴权码是否匹配(Redis 自动处理过期,无需手动检查)
|
||||
if (!authCode.equals(cachedAuthToken)) {
|
||||
log.warn("[handleAuth][鉴权码验证失败,终端手机号: {}, 期望: {}, 实际: {}]",
|
||||
terminalPhone, cachedAuthToken, authCode);
|
||||
if (!authSuccess) {
|
||||
sendCommonResp(socket, terminalPhone, flowId, 0x0102, (byte) 1, codecType, message.getRequestId());
|
||||
return AuthResult.failure("鉴权码错误");
|
||||
return AuthResult.failure("鉴权码验证失败");
|
||||
}
|
||||
|
||||
// 4. 发送通用应答(成功,result_code=0)
|
||||
@@ -289,7 +298,58 @@ public class Jt808ProtocolHandler extends AbstractProtocolHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 鉴权码生成策略 ==========
|
||||
// ========== 鉴权码生成和验证策略 ==========
|
||||
|
||||
/**
|
||||
* 直接验证鉴权码(跳过注册步骤)
|
||||
* <p>
|
||||
* 当设备未注册或缓存过期时,根据设备的认证类型直接验证鉴权码
|
||||
*
|
||||
* @param device 设备信息
|
||||
* @param authCode 设备发送的鉴权码
|
||||
* @param terminalPhone 终端手机号
|
||||
* @return true-验证成功,false-验证失败
|
||||
*/
|
||||
private boolean validateAuthCodeDirectly(IotDeviceRespDTO device, String authCode, String terminalPhone) {
|
||||
try {
|
||||
// 获取生效的认证类型(设备级优先,否则使用产品级)
|
||||
String effectiveAuthType = StrUtil.isNotBlank(device.getAuthType())
|
||||
? device.getAuthType()
|
||||
: device.getProductAuthType();
|
||||
|
||||
if (StrUtil.isBlank(effectiveAuthType)) {
|
||||
log.warn("[validateAuthCodeDirectly][认证类型为空,使用默认策略(终端手机号),终端手机号: {}]", terminalPhone);
|
||||
// 默认策略:使用终端手机号作为鉴权码
|
||||
return terminalPhone.equals(authCode);
|
||||
}
|
||||
|
||||
// 根据认证类型验证
|
||||
if (IotAuthTypeEnum.NONE.getType().equals(effectiveAuthType)) {
|
||||
// 免鉴权:直接通过(或使用终端手机号验证)
|
||||
log.debug("[validateAuthCodeDirectly][免鉴权模式,终端手机号: {}]", terminalPhone);
|
||||
return true;
|
||||
} else if (IotAuthTypeEnum.SECRET.getType().equals(effectiveAuthType)) {
|
||||
// 一机一密:使用设备的 deviceSecret
|
||||
// String deviceSecret = device.getDeviceSecret();
|
||||
return terminalPhone.equals(authCode);
|
||||
} else if (IotAuthTypeEnum.PRODUCT_SECRET.getType().equals(effectiveAuthType)) {
|
||||
// 一型一密:使用产品的 productSecret
|
||||
// 注意:设备信息中可能没有 productSecret,需要从产品获取
|
||||
// 这里暂时使用终端手机号作为回退策略
|
||||
log.warn("[validateAuthCodeDirectly][一型一密需要产品密钥,当前暂不支持直接验证,终端手机号: {},使用终端手机号作为回退", terminalPhone);
|
||||
return terminalPhone.equals(authCode);
|
||||
} else {
|
||||
// 其他类型:使用终端手机号作为回退策略
|
||||
log.warn("[validateAuthCodeDirectly][未知认证类型: {},使用终端手机号作为回退,终端手机号: {}]",
|
||||
effectiveAuthType, terminalPhone);
|
||||
return terminalPhone.equals(authCode);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[validateAuthCodeDirectly][直接验证鉴权码异常,终端手机号: {}]", terminalPhone, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成鉴权码
|
||||
|
||||
Reference in New Issue
Block a user