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