EMQ插件通过HTTP连接认证服务器实现认证
需求
- 在EMQ中添加认证插件,将到来的MQTT连接的ClientID、UserName、Password通过HTTP协议发送到认证服务器,用返回的数据决定是否允许该连接;
- 在连接时和断开时向服务器发送设备上线和离线信息,以支持设备管理的需要。
目前进度
3.12 基本已经掌握了插件开发的模式,但是目前发现也许可以组合几个已有的插件实现我们的需求,如果不用自己编码,虽然配置麻烦一点,但是还是能省下大量时间,初步设想是mysql认证/访问控制插件(主要采用访问控制功能)+http认证插件(加密算法认证)+webhook插件(上下线通知)
已有插件
EMQ中有一个使用http的认证插件,但使用它必须指定superuser认证服务器和访问权限服务器,不能单独开启普通用户认证功能,另外还需要集成上下线通知,我们只用到了他的三分之一功能,并且还需要额外功能,可以考虑的方案有两个,一是改写这个插件,禁用其他功能,并加上通知功能,另一个方案是自己写一个。
方案一的优点是插件部署方便,可以直接借原插件的壳,而不需要重新发布emq的整个release,缺点是代码修改很费时间,也不一定能切割出所有功能。
方案二的优点是编码简单,缺点是需要重新打包整个镜像。主要的挑战在于快速打包发布镜像。
实现路线
- 了解erlang基本语法,完成helloworld
- 编译运行EMQ的插件模板,尝试简单的修改
- 学习使用erlang的http库
- 在插件中加入http请求代码
- 完成简单的全流程
- 加入上下线hook
- 完成插件的config配置
- 整理代码,打包成独立插件并发布源码
Erlang helloworld
在erlang的官网上有一个quick start教程,半天时间基本可以看完所有关于erlang的基础语法,erlang跟golang很像,特别是并发部分,但是编写风格跟C/C++/JAVA系离得比较远,而golang则更靠近,更让我感到亲切。
EMQ插件模板
目前EMQ的插件都以独立仓库的形式开源,因此不需要clone整个emq项目,只需要clone一个插件模板就可以创建插件,而且直接在目录下make即可编译,如果增加库需要学习一下erlang库的链接配置方法。
模板里的代码已经加载了所有钩子(hook),并且在每一个钩子处打印提示信息,插入代码非常方便。
%% Called when the plugin application start
load(Env) ->
emqx:hook('client.connected', fun ?MODULE:on_client_connected/4, [Env]),
emqx:hook('client.disconnected', fun ?MODULE:on_client_disconnected/3, [Env]),
emqx:hook('client.subscribe', fun ?MODULE:on_client_subscribe/3, [Env]),
emqx:hook('client.unsubscribe', fun ?MODULE:on_client_unsubscribe/3, [Env]),
emqx:hook('session.created', fun ?MODULE:on_session_created/3, [Env]),
emqx:hook('session.resumed', fun ?MODULE:on_session_resumed/3, [Env]),
emqx:hook('session.subscribed', fun ?MODULE:on_session_subscribed/4, [Env]),
emqx:hook('session.unsubscribed', fun ?MODULE:on_session_unsubscribed/4, [Env]),
emqx:hook('session.terminated', fun ?MODULE:on_session_terminated/3, [Env]),
emqx:hook('message.publish', fun ?MODULE:on_message_publish/2, [Env]),
emqx:hook('message.delivered', fun ?MODULE:on_message_delivered/3, [Env]),
emqx:hook('message.acked', fun ?MODULE:on_message_acked/3, [Env]),
emqx:hook('message.dropped', fun ?MODULE:on_message_dropped/3, [Env]),
另外在acl(访问控制)的demo里有check函数,在收到连接时检查ClientID、UserName和Password,这里正是我所要的钩子,只需要在这里插入一个http的请求,通过response来判断是否允许连接就可以了。
我在插入http客户端代码的时候遇到了一个小问题:
我在init函数中增加了inets:start(),这是httpc说明中所说的初始化步骤,但是在加入这一步初始化后的http请求会发生错误,而不加入这个函数反而能正常获得response,因此我推测是emq本身早已执行了这一步初始化,因此不应当再次执行初始化。详细的原因我目前就不找了(能用就行)
后续:后面一直报相同的错,学习了一下erlang的报错机制后才发现错的是io:format()语句的参数格式,而不是因为inets:start(),以后还是要注意细节,这么小的一个问题浪费了我一整天的时间来调试,非常不值得。
Erlang HTTP client
Erlang作为爱立信为电信产业设计的语言,在网络方面的库非常发达,http是其标准库的一部分,这里是官方的使用说明。
完成简单的全流程
在解决掉上述的小小问题之后,我成功在连接接入过程中插入了向外界发送http请求的接口。
插件配置
除了代码以外,还需要将整个插件单独整理出来,并且加入简单的配置功能,否则参数直接进代码会带来很大的麻烦。
emq的配置管理用了一个叫clique的库,文档少,官方库里只有readme里一个示例,很难搞清楚用法。
EMQ插件通过HTTP连接认证服务器实现认证的更多相关文章
- Spring Cloud实战 | 第九篇:Spring Cloud整合Spring Security OAuth2认证服务器统一认证自定义异常处理
本文完整代码下载点击 一. 前言 相信了解过我或者看过我之前的系列文章应该多少知道点我写这些文章包括创建 有来商城youlai-mall 这个项目的目的,想给那些真的想提升自己或者迷茫的人(包括自己- ...
- EMQ插件组合实现物联网边缘平台的设备通信管理
上一篇随笔我简单的记录了我对EMQ插件开发的了解过程,最后发现还是可以组合复用已有插件,因此这篇随笔用于记录使用的情况以及是否达到预期. 首先测试mysql认证插件的使用方式: emqx_auth_m ...
- freeradius整合AD域作anyconncet认证服务器
一.服务器要求 Radius服务器:centos6.6.hostname.selinux disabled.stop iptables AD域服务器:Windows Server 2008 R2 E ...
- Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC)
XMPP(Extensible Messaging and Presence Protocol)是一种网络即时通讯协议,它基于XML,具有很强的扩展性,被广泛使用在即时通讯软件.网络游戏聊天.Web聊 ...
- SSH如何通过公钥连接云服务器
导读 通常我们连接远程服务器(linux)windows下通过putty或xshell等工具远程连接.linux下可以直接通过ssh命令连接.其实这两者都是一致的,都是通过ssh协议进行传输. 如果我 ...
- Comet:基于 HTTP 长连接的“服务器推”技术解析
原文链接:http://www.cnblogs.com/deepleo/p/Comet.html 一.背景介绍 传统web请求,是显式的向服务器发送http Request,拿到Response后显示 ...
- Comet:基于 HTTP 长连接的“服务器推”技术
“服务器推”技术的应用 请访问 Ajax 技术资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档.教程.论坛.blog.wiki 和新闻.任何 Ajax 的新信息都能在这里找到. c ...
- 转载:Comet:基于 HTTP 长连接的“服务器推”技术
转自:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/ 很多应用譬如监控.即时通信.即时报价系统都需要将后台发生的变化实时传送到客户端而无须客 ...
- Pure-ftpd无法连接到服务器 425错误
今天是五一假期的前一天,闲来没事,打开自己的博客,发现很久没有备份数据了,由于工作方面的原因,自己慢慢的退出了技术界,但本人还是依然向往技术界啊!各位技术宅们,加油! 问题发现 当我打开FTP客户端软 ...
随机推荐
- 手把手教你上传文件到GitHub上(已获取ssh密钥)
如何提交一个文件到GitHub(已经生成ssh key) 1.新建一个文件夹,当作本地仓库 2.初始化仓库 $git init 3.将想要上传的东西复制到仓库中 4.将文件提交到暂存区 $git ad ...
- HTML-简单动画
简单动画 (1)简单动画通常称之为“过渡transition” Transition-property:需要过渡的属性,但是并非所有的属性都支持过渡. Transition-duration:过渡的时 ...
- linux开启Rsyslog服务收集日志
一.查看是否安装了rsyslog服务 [root@server- ~]# yum install -y rsyslog 已加载插件:fastestmirror Loading mirror speed ...
- 机器学习聚类算法之K-means
一.概念 K-means是一种典型的聚类算法,它是基于距离的,是一种无监督的机器学习算法. K-means需要提前设置聚类数量,我们称之为簇,还要为之设置初始质心. 缺点: 1.循环计算点到质心的距离 ...
- [SCOI2016]幸运数字(线性基,倍增)
[SCOI2016]幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作 ...
- 详解PHP文件下载的原理和实现
通常文件下载过程是十分简单的,建立一个链接指向到目标文件就可以了.例如下面的链接: XML/HTML代码 <a href=http://www.xxx.com/xxx.rar>点击下载文件 ...
- 如何将vim打造成Linux下的source insight
编写者:龙诗科 邮箱:longshike2010@163.com 2016-01-06 众所周知,windows下的source insight是阅读项目代码的神器,其神奇之处在于可以根据当前鼠标所指 ...
- node.js 实现 AES CTR 加解密
node.js 实现 AES CTR 加解密 node aesctr 前言 由于最近我们在做一款安全的文件分享 App, 所有文件均需要使用 aes ctr 来进行加密,aes key 还有一整套完整 ...
- 移动端布局基础viewport
划重点 手机屏幕相对着桌面浏览器小,传统网页的设计在手机上体验糟糕 Apple 在移动版 Safari 中定义了 viewport meta 标签(如果没记错最早提出的话),用于创建一个虚拟窗口(la ...
- 读取xml文件中的配置参数实例_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 paras.xml文件 <?xml version="1.0" encoding=" ...