feat:【IoT 物联网】增加网关 HTTP 协议的鉴权,基于 JWT 轻量级
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import cn.hutool.system.SystemUtil;
|
||||
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
|
||||
|
||||
/**
|
||||
* IoT 设备消息的工具类
|
||||
* IoT 设备【消息】的工具类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user