feat:【IoT 物联网】增加网关 HTTP 协议的鉴权,基于 JWT 轻量级

This commit is contained in:
YunaiV
2025-06-03 13:22:55 +08:00
parent 1498389d26
commit 643cc4cfd2
40 changed files with 793 additions and 498 deletions

View File

@@ -1,5 +1,15 @@
package cn.iocoder.yudao.module.iot.core.biz;
// TODO @芋艿:待实现
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
/**
* IoT 设备通用 API
*
* @author haohao
*/
public interface IotDeviceCommonApi {
CommonResult<Boolean> authDevice(IotDeviceAuthReqDTO authReqDTO);
}

View File

@@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.iot.core.biz.dto;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
/**
* IoT 设备认证 Request DTO
*
* @author 芋道源码
*/
@Data
public class IotDeviceAuthReqDTO {
/**
* 客户端 ID
*/
@NotEmpty(message = "客户端 ID 不能为空")
private String clientId;
/**
* 用户名
*/
@NotEmpty(message = "用户名不能为空")
private String username;
/**
* 密码
*/
@NotEmpty(message = "密码不能为空")
private String password;
}

View File

@@ -0,0 +1,85 @@
package cn.iocoder.yudao.module.iot.core.util;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.HmacAlgorithm;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* IoT 设备【认证】的工具类,参考阿里云
*
* @see <a href="https://help.aliyun.com/zh/iot/user-guide/how-do-i-obtain-mqtt-parameters-for-authentication">如何计算 MQTT 签名参数</a>
*/
public class IotDeviceAuthUtils {
/**
* 认证信息
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class AuthInfo {
/**
* 客户端 ID
*/
private String clientId;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
}
/**
* 设备信息
*/
@Data
public static class DeviceInfo {
private String productKey;
private String deviceName;
}
public static AuthInfo getAuthInfo(String productKey, String deviceName, String deviceSecret) {
String clientId = buildClientId(productKey, deviceName);
String username = buildUsername(productKey, deviceName);
String content = "clientId" + clientId +
"deviceName" + deviceName +
"deviceSecret" + deviceSecret +
"productKey" + productKey;
String password = buildPassword(deviceSecret, content);
return new AuthInfo(clientId, username, password);
}
private static String buildClientId(String productKey, String deviceName) {
return String.format("%s.%s", productKey, deviceName);
}
private static String buildUsername(String productKey, String deviceName) {
return String.format("%s&%s", deviceName, productKey);
}
private static String buildPassword(String deviceSecret, String content) {
return DigestUtil.hmac(HmacAlgorithm.HmacSHA256, deviceSecret.getBytes())
.digestHex(content);
}
public static DeviceInfo parseUsername(String username) {
String[] usernameParts = username.split("&");
if (usernameParts.length != 2) {
return null;
}
return new DeviceInfo().setProductKey(usernameParts[1]).setDeviceName(usernameParts[0]);
}
}

View File

@@ -6,7 +6,7 @@ import cn.hutool.system.SystemUtil;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
/**
* IoT 设备消息的工具类
* IoT 设备消息的工具类
*
* @author 芋道源码
*/