Commit fa40ae1dbd368628a9e8a0ef0b6e0636be61ee45

Authored by YunaiV
1 parent 8043ce61

【代码评审】IoT:MQTT 连接参数

yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/IotDeviceUpstreamApi.java
... ... @@ -71,6 +71,7 @@ public interface IotDeviceUpstreamApi {
71 71 @PostMapping(PREFIX + "/add-topology")
72 72 CommonResult<Boolean> addDeviceTopology(@Valid @RequestBody IotDeviceTopologyAddReqDTO addReqDTO);
73 73  
  74 + // TODO @芋艿:考虑 http 认证
74 75 /**
75 76 * 认证 Emqx 连接
76 77 *
... ...
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceEmqxAuthReqDTO.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
3 3 import jakarta.validation.constraints.NotEmpty;
4 4 import lombok.Data;
5 5  
  6 +// TODO @芋艿:要不要继承 IotDeviceUpstreamAbstractReqDTO
6 7 /**
7 8 * IoT 认证 Emqx 连接 Request DTO
8 9 *
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
... ... @@ -177,6 +177,7 @@ public class IotDeviceController {
177 177 return success(true);
178 178 }
179 179  
  180 + // TODO @haohao:是不是默认详情接口,不返回 secret,然后这个接口,用于统一返回。然后接口名可以更通用一点。
180 181 @GetMapping("/mqtt-connection-params")
181 182 @Operation(summary = "获取 MQTT 连接参数")
182 183 @PreAuthorize("@ss.hasPermission('iot:device:mqtt-connection-params')")
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
... ... @@ -123,9 +123,7 @@ public class IotDeviceServiceImpl implements IotDeviceService {
123 123 private void initDevice(IotDeviceDO device, IotProductDO product) {
124 124 device.setProductId(product.getId()).setProductKey(product.getProductKey())
125 125 .setDeviceType(product.getDeviceType());
126   - // 生成并设置必要的字段
127   - // TODO @芋艿:各种 mqtt 是不是可以简化!
128   - // clientId、username、password 根据规则实时生成
  126 + // 生成密钥
129 127 device.setDeviceSecret(generateDeviceSecret());
130 128 // 设置设备状态为未激活
131 129 device.setState(IotDeviceStateEnum.INACTIVE.getState());
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java
... ... @@ -280,6 +280,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
280 280 sendDeviceMessage(message, device);
281 281 }
282 282  
  283 + // TODO @haohao:建议返回 boolean;
283 284 @Override
284 285 public Boolean authenticateEmqxConnection(IotDeviceEmqxAuthReqDTO authReqDTO) {
285 286 log.info("[authenticateEmqxConnection][认证 Emqx 连接: {}]", authReqDTO);
... ... @@ -303,6 +304,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
303 304 String deviceSecret = device.getDeviceSecret();
304 305 String clientId = authReqDTO.getClientId();
305 306 MqttSignResult sign = MqttSignUtils.calculate(productKey, deviceName, deviceSecret, clientId);
  307 + // TODO @haohao:notEquals,尽量不走取反逻辑哈
306 308 if (!StrUtil.equals(sign.getPassword(), authReqDTO.getPassword())) {
307 309 log.error("[authenticateEmqxConnection][认证失败,密码不正确]");
308 310 return Boolean.FALSE;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/util/MqttSignUtils.java
... ... @@ -8,12 +8,15 @@ import java.nio.charset.StandardCharsets;
8 8  
9 9 /**
10 10 * MQTT 签名工具类
11   - * 提供静态方法来计算 MQTT 连接参数。
  11 + *
  12 + * 提供静态方法来计算 MQTT 连接参数
12 13 */
13 14 public class MqttSignUtils {
14 15  
15 16 private static final String SIGN_METHOD = "hmacsha256";
16 17  
  18 + // TODO @haohao:calculate 方法,可以融合么?
  19 +
17 20 /**
18 21 * 计算 MQTT 连接参数
19 22 *
... ... @@ -25,11 +28,11 @@ public class MqttSignUtils {
25 28 public static MqttSignResult calculate(String productKey, String deviceName, String deviceSecret) {
26 29 String clientId = productKey + "." + deviceName;
27 30 String username = deviceName + "&" + productKey;
  31 + // 生成 password
  32 + // TODO @haohao:signContent 和 signContentBuilder 风格保持统一的实现哈
28 33 String signContent = String.format("clientId%sdeviceName%sdeviceSecret%sproductKey%s",
29 34 clientId, deviceName, deviceSecret, productKey);
30   -
31 35 String password = sign(signContent, deviceSecret);
32   -
33 36 return new MqttSignResult(clientId, username, password);
34 37 }
35 38  
... ... @@ -54,6 +57,7 @@ public class MqttSignUtils {
54 57 return new MqttSignResult(clientId, username, password);
55 58 }
56 59  
  60 + // TODO @haohao:hutool 貌似有工具类可以用哈。
57 61 private static String sign(String content, String key) {
58 62 try {
59 63 Mac mac = Mac.getInstance(SIGN_METHOD);
... ... @@ -81,7 +85,9 @@ public class MqttSignUtils {
81 85 * MQTT 签名结果类
82 86 */
83 87 @Getter
  88 + // TODO @haohao:可以用 lombok 哈
84 89 public static class MqttSignResult {
  90 +
85 91 private final String clientId;
86 92 private final String username;
87 93 private final String password;
... ...