feat:【IoT 物联网】增加网关 HTTP 协议的鉴权,基于 JWT 轻量级(已测试)
This commit is contained in:
parent
643cc4cfd2
commit
a0a26c3d64
|
@ -10,6 +10,7 @@ import jakarta.annotation.security.PermitAll;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
@ -30,7 +31,7 @@ public class IoTDeviceApiImpl implements IotDeviceCommonApi {
|
||||||
@Override
|
@Override
|
||||||
@PostMapping(RpcConstants.RPC_API_PREFIX + "/iot/device/auth")
|
@PostMapping(RpcConstants.RPC_API_PREFIX + "/iot/device/auth")
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<Boolean> authDevice(IotDeviceAuthReqDTO authReqDTO) {
|
public CommonResult<Boolean> authDevice(@RequestBody IotDeviceAuthReqDTO authReqDTO) {
|
||||||
return success(deviceService.authDevice(authReqDTO));
|
return success(deviceService.authDevice(authReqDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,6 @@ public interface IotDeviceService {
|
||||||
* @param authReqDTO 认证信息
|
* @param authReqDTO 认证信息
|
||||||
* @return 是否认证成功
|
* @return 是否认证成功
|
||||||
*/
|
*/
|
||||||
boolean authDevice(IotDeviceAuthReqDTO authReqDTO);
|
boolean authDevice(@Valid IotDeviceAuthReqDTO authReqDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,13 @@ package cn.iocoder.yudao.module.iot.gateway.protocol.http.router;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
|
import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
|
||||||
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
|
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
|
||||||
import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer;
|
import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer;
|
||||||
import cn.iocoder.yudao.module.iot.core.util.IotDeviceAuthUtils;
|
import cn.iocoder.yudao.module.iot.core.util.IotDeviceAuthUtils;
|
||||||
import cn.iocoder.yudao.module.iot.gateway.protocol.http.IotHttpUpstreamProtocol;
|
import cn.iocoder.yudao.module.iot.gateway.protocol.http.IotHttpUpstreamProtocol;
|
||||||
|
@ -47,7 +49,7 @@ public class IotHttpAuthHandler extends IotHttpAbstractHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Object> handle0(RoutingContext context) {
|
public CommonResult<Object> handle0(RoutingContext context) {
|
||||||
// 解析参数
|
// 1. 解析参数
|
||||||
JsonObject body = context.body().asJsonObject();
|
JsonObject body = context.body().asJsonObject();
|
||||||
String clientId = body.getString("clientId");
|
String clientId = body.getString("clientId");
|
||||||
if (StrUtil.isEmpty(clientId)) {
|
if (StrUtil.isEmpty(clientId)) {
|
||||||
|
@ -62,20 +64,23 @@ public class IotHttpAuthHandler extends IotHttpAbstractHandler {
|
||||||
throw invalidParamException("password 不能为空");
|
throw invalidParamException("password 不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行认证
|
// 2.1 执行认证
|
||||||
CommonResult<Boolean> result = deviceClientService.authDevice(new IotDeviceAuthReqDTO()
|
CommonResult<Boolean> result = deviceClientService.authDevice(new IotDeviceAuthReqDTO()
|
||||||
.setClientId(clientId).setUsername(username).setPassword(password));
|
.setClientId(clientId).setUsername(username).setPassword(password));
|
||||||
if (result == null || !result.isSuccess()) {
|
result.checkError();;
|
||||||
|
if (!BooleanUtil.isTrue(result.getData())) {
|
||||||
throw exception(DEVICE_AUTH_FAIL);
|
throw exception(DEVICE_AUTH_FAIL);
|
||||||
}
|
}
|
||||||
|
// 2.2 生成 Token
|
||||||
// 生成 Token
|
|
||||||
IotDeviceAuthUtils.DeviceInfo deviceInfo = deviceTokenService.parseUsername(username);
|
IotDeviceAuthUtils.DeviceInfo deviceInfo = deviceTokenService.parseUsername(username);
|
||||||
Assert.notNull(deviceInfo, "设备信息不能为空");
|
Assert.notNull(deviceInfo, "设备信息不能为空");
|
||||||
String token = deviceTokenService.createToken(deviceInfo.getProductKey(), deviceInfo.getDeviceName());
|
String token = deviceTokenService.createToken(deviceInfo.getProductKey(), deviceInfo.getDeviceName());
|
||||||
Assert.notBlank(token, "生成 token 不能为空位");
|
Assert.notBlank(token, "生成 token 不能为空位");
|
||||||
|
|
||||||
// TODO @芋艿:发送上线消息;
|
// 3. 执行上线
|
||||||
|
deviceMessageProducer.sendDeviceMessage(IotDeviceMessage.of(deviceInfo.getProductKey(), deviceInfo.getDeviceName(),
|
||||||
|
protocol.getServerId())
|
||||||
|
.ofStateOnline());
|
||||||
|
|
||||||
// 构建响应数据
|
// 构建响应数据
|
||||||
return success(MapUtil.of("token", token));
|
return success(MapUtil.of("token", token));
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.iot.gateway.service.device;
|
package cn.iocoder.yudao.module.iot.gateway.service.device;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
|
import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
|
||||||
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
|
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
|
||||||
|
@ -31,7 +32,7 @@ public class IotDeviceClientServiceImpl implements IotDeviceCommonApi {
|
||||||
public void init() {
|
public void init() {
|
||||||
IotGatewayProperties.RpcProperties rpc = gatewayProperties.getRpc();
|
IotGatewayProperties.RpcProperties rpc = gatewayProperties.getRpc();
|
||||||
restTemplate = new RestTemplateBuilder()
|
restTemplate = new RestTemplateBuilder()
|
||||||
.rootUri(rpc.getUrl() + "/rpc-api/iot/device/")
|
.rootUri(rpc.getUrl() + "/rpc-api/iot/device")
|
||||||
.readTimeout(rpc.getReadTimeout())
|
.readTimeout(rpc.getReadTimeout())
|
||||||
.connectTimeout(rpc.getConnectTimeout())
|
.connectTimeout(rpc.getConnectTimeout())
|
||||||
.build();
|
.build();
|
||||||
|
@ -39,7 +40,7 @@ public class IotDeviceClientServiceImpl implements IotDeviceCommonApi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> authDevice(IotDeviceAuthReqDTO authReqDTO) {
|
public CommonResult<Boolean> authDevice(IotDeviceAuthReqDTO authReqDTO) {
|
||||||
return doPost("auth", authReqDTO);
|
return doPost("/auth", authReqDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -48,6 +49,7 @@ public class IotDeviceClientServiceImpl implements IotDeviceCommonApi {
|
||||||
CommonResult<Boolean> result = restTemplate.postForObject(url, requestBody,
|
CommonResult<Boolean> result = restTemplate.postForObject(url, requestBody,
|
||||||
(Class<CommonResult<Boolean>>) (Class<?>) CommonResult.class);
|
(Class<CommonResult<Boolean>>) (Class<?>) CommonResult.class);
|
||||||
log.info("[doPost][url({}) requestBody({}) result({})]", url, requestBody, result);
|
log.info("[doPost][url({}) requestBody({}) result({})]", url, requestBody, result);
|
||||||
|
Assert.notNull(result, "请求结果不能为空");
|
||||||
return result;
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[doPost][url({}) requestBody({}) 发生异常]", url, requestBody, e);
|
log.error("[doPost][url({}) requestBody({}) 发生异常]", url, requestBody, e);
|
||||||
|
|
Loading…
Reference in New Issue