1. 前言

在物联网教学场景中,我们对接的核心终端设备以华为鸿蒙 LiteOS-M 等轻量级嵌入式操作系统为主,这类系统的核心特征是面向低算力、低成本的单片机/微控制器(如STM32、Hi3861等)设计,硬件层面普遍无 RTC 实时时钟模块、软件层面无系统级时间管理能力,完全无法生成 JetLinks 官方原生认证机制所需的精准时间戳;同时,MD5 哈希算法的实现需要占用额外的 Flash/内存空间,且会消耗单片机有限的 CPU 算力,对于以教学为核心的场景而言,既增加了嵌入式代码的开发复杂度,也偏离了“设备接入核心逻辑”的教学重点。

JetLinks 官方原生的 MQTT 认证机制依赖“时间戳+MD5 签名”生成动态凭证,这一设计虽适用于具备完整系统能力的智能设备,但在鸿蒙 LiteOS-M 这类轻量级嵌入式教学场景中,成为了设备接入的核心障碍:学生需要花费大量时间调试时间同步、MD5 算法移植问题,而非聚焦于 MQTT 协议通信、设备数据上报/指令接收等核心教学目标。

为适配鸿蒙 LiteOS-M 等无系统时间、低算力嵌入式设备的教学场景,本次对 JetLinks 官方协议模块(jetlinks-official-protocol)进行定制化修改,摒弃原生的时间戳+MD5 动态签名认证逻辑,简化为直接使用设备预配置的 secureId 作为 MQTT 用户名、secureKey 作为 MQTT 密码 的固定凭证认证方式。该方式既满足教学场景下的基础身份校验需求,又彻底消除了时间戳、MD5 算法带来的适配成本,让学生能够快速完成设备接入,聚焦于物联网通信的核心知识点学习。

教学场景适配的核心优势

  1. 降低入门门槛:无需讲解/实现 NTP 时间同步、MD5 哈希算法,学生只需掌握 MQTT 客户端的用户名/密码配置,即可完成设备认证接入;
  2. 贴合硬件实际:完全匹配鸿蒙 LiteOS-M 无系统时间、低算力的硬件特征,避免“为适配认证而额外扩展硬件(如外接 RTC 模块)”的非教学必要操作;
  3. 聚焦核心教学目标:将教学重点回归到“MQTT 协议原理、设备与平台的双向通信、数据上报/指令下发”等物联网核心知识点,而非算法移植、时间校准等适配性工作;
  4. 便于课堂调试:固定凭证认证逻辑简单,设备接入失败时可快速定位“用户名/密码错误”“设备配置未同步”等问题,提升课堂教学效率。

2. 代码修订

2.1 基本情况说明

官方代码目前通用的版本是v3,因此在v3版本的基础上,修改代码,使用java 17 编译,这里本人给出修改后的git路径https://gitee.com/zhengjunqiang/jetlinks-official-protocol.git

在这里插入图片描述

2.2 代码修改

package org.jetlinks.protocol.official;

import org.jetlinks.core.Value;
import org.jetlinks.core.defaults.Authenticator;
import org.jetlinks.core.device.*;
import reactor.core.publisher.Mono;

import javax.annotation.Nonnull;

/**
 * JetLinks设备认证器:直接使用secureId作为用户名、secureKey作为密码进行认证
 */
public class JetLinksAuthenticator implements Authenticator {

    @Override
    public Mono<AuthenticationResponse> authenticate(@Nonnull AuthenticationRequest request,
            @Nonnull DeviceRegistry registry) {
        // 仅支持MQTT认证请求
        if (!(request instanceof MqttAuthenticationRequest)) {
            return Mono.just(AuthenticationResponse.error(400, "不支持的授权类型:" + request));
        }
        MqttAuthenticationRequest mqtt = ((MqttAuthenticationRequest) request);

        // 根据客户端ID获取设备,再执行认证逻辑
        return registry
                .getDevice(mqtt.getClientId())
                .flatMap(device -> authenticate(request, device));
    }

    @Override
    public Mono<AuthenticationResponse> authenticate(@Nonnull AuthenticationRequest request,
            @Nonnull DeviceOperator deviceOperation) {
        // 仅处理MQTT认证请求
        if (!(request instanceof MqttAuthenticationRequest)) {
            return Mono.just(AuthenticationResponse.error(400, "不支持的授权类型:" + request));
        }
        MqttAuthenticationRequest mqtt = ((MqttAuthenticationRequest) request);

        // 1. 直接获取请求中的用户名(secureId)和密码(secureKey)
        String requestSecureId = mqtt.getUsername();
        String requestSecureKey = mqtt.getPassword();

        // 2. 校验用户名/密码是否为空(基础校验)
        if (requestSecureId == null || requestSecureId.isBlank()
                || requestSecureKey == null || requestSecureKey.isBlank()) {
            return Mono.just(AuthenticationResponse.error(401, "用户名或密码不能为空"));
        }

        // 3. 获取设备配置中的secureId和secureKey,进行比对
        return deviceOperation.getConfigs("secureId", "secureKey")
                .map(conf -> {
                    // 从设备配置中读取预存的secureId和secureKey
                    String deviceSecureId = conf.getValue("secureId").map(Value::asString).orElse(null);
                    String deviceSecureKey = conf.getValue("secureKey").map(Value::asString).orElse(null);

                    // 4. 比对请求值与设备配置值
                    if (requestSecureId.equals(deviceSecureId) && requestSecureKey.equals(deviceSecureKey)) {
                        // 认证成功,返回设备ID
                        return AuthenticationResponse.success(deviceOperation.getDeviceId());
                    } else {
                        // 认证失败,提示密钥错误
                        return AuthenticationResponse.error(401, "secureId或secureKey错误");
                    }
                });
    }
}

3. 对接测试

代码修订之后,根据官方的协议包导入文档https://doc.jetlinks.cn/Best_practices/Device_access.html#系统配置,使用mqtt测试

步骤1 创建协议

在这里插入图片描述

在这里插入图片描述

步骤2 添加网络组件

在这里插入图片描述

步骤3 添加 设备接入网关

在这里插入图片描述

步骤4 添加 产品及设备

在这里插入图片描述

在这里插入图片描述

步骤5 mqttx 对接

在这里插入图片描述

在这里插入图片描述

连接成功
在这里插入图片描述

4. 结论

本次针对 JetLinks 官方协议模块(jetlinks-official-protocol)的定制化修改,成功解决了鸿蒙 LiteOS-M 等轻量级嵌入式设备在教学场景中接入 JetLinks 平台的核心痛点。通过摒弃原生“时间戳+MD5 签名”的复杂认证逻辑,采用“secureId 作为 MQTT 用户名、secureKey 作为 MQTT 密码”的固定凭证认证方式,实现了三大核心目标:

1. 适配教学场景硬件特性

修改后的认证机制完全脱离了对系统时间(RTC 模块)和高性能算力的依赖,完美匹配 STM32、Hi3861 等单片机及鸿蒙 LiteOS-M 系统的硬件限制,无需额外扩展 RTC 模块或移植复杂的 MD5 算法库,降低了硬件适配成本,让学生可直接基于教学用嵌入式设备完成实操。

2. 聚焦物联网核心教学目标

简化后的认证逻辑剥离了非核心的算法实现、时间同步等适配性工作,将教学重点回归到 MQTT 协议原理、设备与平台双向通信、数据上报与指令下发等核心知识点上。学生无需花费大量时间调试签名有效性、时间校准等问题,可快速完成设备接入全流程实操,提升了课堂教学效率与知识吸收效果。

3. 保障接入稳定性与可调试性

固定凭证的认证方式逻辑清晰、流程简洁,设备接入失败时可快速定位“用户名/密码错误”“设备配置未同步”等核心问题,减少了课堂调试的复杂度。经 MQTTX 客户端及教学用嵌入式设备实测,修改后的协议模块可稳定实现设备认证、数据交互功能,完全满足物联网教学场景的实操需求。

4. 具备良好的扩展性与复用性

本次修改基于 JetLinks v3 官方版本开发,兼容 Java 17 编译环境,修改后的代码已开源至 Gitee 仓库,可直接集成到 JetLinks 教学平台中复用。同时,该认证方式支持与 JetLinks 平台的产品管理、设备管理、规则引擎等核心模块无缝对接,后续可根据教学需求进一步扩展权限控制、数据加密等进阶功能,适配更复杂的教学场景。

综上,本次定制化修改既解决了轻量级嵌入式设备接入 JetLinks 平台的技术障碍,又贴合物联网教学的核心诉求,为学生搭建了“低门槛、高聚焦、易实操”的设备接入实践环境,可作为物联网教学中 JetLinks 平台与嵌入式设备对接的优选方案。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐