看过之前的文章就知道,我之前是通过搞插件,或者通过里面的MongoDB来进行EMQ的鉴权登录和权限验证。但是前段时间发现,还是通过HTTP WebHook 方式来调用鉴权接口比较适合实际使用。还是实现设备分配一个device_id和device_key两个信息。即登录我们的业务服务器,同时登录EMQ通信服务器。免去了中间获取临时登录MQTT-Token的流程。
  下面就看这么实现基于HTTP的Auth.
  首先在EMQ的后台,管理-插件-emqx_auth_http中开启插件。(注意由于距离上次已经过去半年了,EMQ也已经升级到了3.x版本了,我这里使用EMQ 3.1.0 版本, 具体配置跟之前是差不多的。)


  下面这段代码就是主要的鉴权及权限验证代码。主要有三个WebHook函数。auth、superuser、acl。

 @RestController
@RequestMapping(value="/iot/v1/mqtt")
public class MqttAPIController { @Autowired
private DeviceService deviceService; @RequestMapping(value="/auth")
public ResponseRESTModel auth(HttpServletResponse response,
String clientid, String username, String password){
String device_id = username;
DeviceModel model = deviceService.selectOneByDeviceID(device_id);
if(model == null){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return ResponseRESTUtils.error(500, false);
}
boolean flag = SecretUtils.matchBcryptPassword(password, model.getDevice_key());
if(flag == false || !model.getUuid().equals(clientid)){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return ResponseRESTUtils.error(500, false);
}
return ResponseRESTUtils.success(true);
}
@RequestMapping(value="/superuser")
public ResponseRESTModel superuser(HttpServletResponse response,
String clientid, String username){
//默认没有超级用户权限
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return ResponseRESTUtils.success(true);
}
@RequestMapping(value="/acl")
public ResponseRESTModel acl(HttpServletResponse response,
String clientid, String username, String access, String ipaddr, String topic){
//iot/uuid/#
String _acl = "iot/" + clientid + "/";
if(CheckUtils.isEmpty(topic)){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return ResponseRESTUtils.error(500, false);
}
if(topic.startsWith(_acl)){
return ResponseRESTUtils.success(true);
}
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return ResponseRESTUtils.error(500, false);
}
}

  auth:是在每次登录是都会验证一次。
  superuser:会在登录的时候调用判断是否有超级用户权限
  acl:这个会在发布或订阅数据的时候请求,判断是否允许发布或订阅,不会每次都判断,只对新Topic才进行判断,然后缓存在EMQ里面。
  WebHook采用就是标准的HTTP请求,利用HTTP response的返回状态码表示是否通过。
  详细参考官方文档: https://developer.emqx.io/docs/broker/v3/cn/plugins.html#http
  通过这种方式,比之前通过查询数据有更强的业务扩展性。比如可以判断设备是否被禁用。设备的ACL权限问题,可以更细微级控制。但是毕竟通过HTTP方式会有性能损耗,这一点为鉴权功能单独划分模块。从业务服务器独立出来单独成为一个服务。

物联网架构成长之路系列文章目录: https://www.cnblogs.com/wunaozai/p/8067577.html

本文地址: https://www.cnblogs.com/wunaozai/p/11147024.html
参考资料: https://developer.emqx.io/docs/broker/v3/cn/plugins.html#http

物联网架构成长之路(31)-EMQ基于HTTP权限验证的更多相关文章

  1. 物联网架构成长之路(6)-EMQ权限控制

    1. 前言 EMQTT属于一个比较小众的开源软件,很多资料不全,很麻烦,很多功能都是靠猜测,还有就是看官方提供的那几个插件,了解. 2. 说明 上一小节的插件 emq_plugin_wunaozai ...

  2. 物联网架构成长之路(3)-EMQ消息服务器了解

    1. 了解 物联网最基础的就是通信了.通信协议,物联网协议好像有那么几个,以前各个协议都有优劣,最近一段时间,好像各大厂商都采用MQTT协议,所以我也不例外,不搞特殊,采用MQTT协议,选定了协议,接 ...

  3. 物联网架构成长之路(33)-EMQ数据存储到influxDB

    一.前言 时隔一年半,技术变化特别快,学习也要跟上才行.以前写过EMQ数据转存问题,当时用了比较笨的方法,通过写插件的方式,把MQTT里面的数据发送到数据库进行存储.当时也是为了学习erlang和em ...

  4. 物联网架构成长之路(4)-EMQ插件创建

    1. 说明 以下用到的知识,是建立在我目前所知道的知识领域,以后如果随着知识的拓展,不一定会更新内容.由于不是EMQ公司的人,EMQ的文档又很少,很多知识点都是靠猜的.2. 一些资料 架构设计 htt ...

  5. 物联网架构成长之路(5)-EMQ插件配置

    1. 前言 上一小结说了插件的创建,这一节主要怎么编写代码,以及具体流程之类的.2. 增加一句Hello World 修改 ./deps/emq_plugin_wunaozai/src/emq_plu ...

  6. 物联网架构成长之路(7)-EMQ权限验证小结

    1. 前言 经过前面几小节,讲了一下插件开发,这一小节主要对一些代码和目录结构进行讲解,这些都是测试过程中一些个人经验,不一定是官方做法.而且也有可能会因为版本不一致导致差异. 2. 目录结构 这个目 ...

  7. 物联网架构成长之路(25)-Docker构建项目用到的镜像1

    0. 前言 现在项目处于初级阶段,按照规划,先构建几个以后可能会用到的Image,并上传到阿里云的Docker仓库.以后博客中用到的Image,大部分都会用到这几个基础的Image,构建一个简单的物联 ...

  8. 物联网架构成长之路(37)-基于C#开发串口工具

    0. 前言 作为物联网平台开发,最基础的工具链还是要有的.前几篇博客,介绍了用C#开发一个MQTT的客户端,用于模拟设备连接平台,并发送数据到平台.但是对于一些硬件来说,可能会用到串口uart来发送数 ...

  9. 物联网架构成长之路(35)-利用Netty解析物联网自定义协议

    一.前言 前面博客大部分介绍了基于EMQ中间件,通信协议使用的是MQTT,而传输的数据为纯文本数据,采用JSON格式.这种方式,大部分一看就知道是熟悉Web开发.软件开发的人喜欢用的方式.由于我也是做 ...

随机推荐

  1. spring cloud 2.x版本 Gateway熔断、限流教程

    前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ...

  2. 一个有用的排序函数,array_multisort(),下面的一个用法是根据二维数组里的一个字段值的大小,对该二维数组进行重新排序

    从二维数组$cashes中取出一列 'store_id'(二维数组中的每个一维数组都有的字段),按照这个的大小排序,对二维数组$caches里面的一维数组进行重新排序 实际应用如下 想让相同部门的排在 ...

  3. rxjava介绍

    Observable 在RxJava1.x中,最熟悉的莫过于Observable这个类了,笔者刚使用RxJava2.x时,创建一个Observable后,顿时是懵逼的.因为我们熟悉的Subscribe ...

  4. GO 数组

    一.数组(Array) 1.1 什么是数组 Go 语言提供了数组类型的数据结构. 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形.字符串或者自定义类型. ...

  5. C#关闭多线程程序

    Process[] processes = System.Diagnostics.Process.GetProcesses(); //获得所有进程 foreach (Process p in proc ...

  6. .net WebApi 批量文件进行压缩zip以二进制流传输至前端(Vue)下载

    前言:最近接了个项目,需要进行将服务端生成的文件进行打包压缩供前端下载,百度查了下资料,决定采用SharpZipLib C#开园的压缩解压库进行服务器文件压缩,在实现过程,郁闷的是前端接收下载下来的压 ...

  7. PHP+Ajax点击加载更多列表数据实例

    一款简单实用的PHP+Ajax点击加载更多列表数据实例,实现原理:通过“更多”按钮向服务端发送Ajax请求,PHP根据分页参数查询将最新的几条记录,数据以JSON形式返回,前台Query解析JSON数 ...

  8. [转]Doing more with Outlook filter and SQL DASL syntax

    本文转自:https://blogs.msdn.microsoft.com/andrewdelin/2005/05/10/doing-more-with-outlook-filter-and-sql- ...

  9. 【jQuery】jQuery基础

    jQuery介绍 jQuery是一个轻量级JS库,使用十分简单: jQuery的核心是选择器,用于获取页面元素: jQuery提供了大量高效的方法,开发速度大幅提升: jQuery选择器 jQuery ...

  10. 去掉没用的参数的warning

    #define UNUSED(x) ((void)(x)) void fun(int noused_arg, int b){ UNUSED(noused_arg); printf("%d\n ...