zoukankan      html  css  js  c++  java
  • EMQ插件通过HTTP连接认证服务器实现认证

    需求

    1. 在EMQ中添加认证插件,将到来的MQTT连接的ClientID、UserName、Password通过HTTP协议发送到认证服务器,用返回的数据决定是否允许该连接;
    2. 在连接时和断开时向服务器发送设备上线和离线信息,以支持设备管理的需要。

    目前进度

    3.12 基本已经掌握了插件开发的模式,但是目前发现也许可以组合几个已有的插件实现我们的需求,如果不用自己编码,虽然配置麻烦一点,但是还是能省下大量时间,初步设想是mysql认证/访问控制插件(主要采用访问控制功能)+http认证插件(加密算法认证)+webhook插件(上下线通知)

    已有插件

    EMQ中有一个使用http的认证插件,但使用它必须指定superuser认证服务器和访问权限服务器,不能单独开启普通用户认证功能,另外还需要集成上下线通知,我们只用到了他的三分之一功能,并且还需要额外功能,可以考虑的方案有两个,一是改写这个插件,禁用其他功能,并加上通知功能,另一个方案是自己写一个。

    方案一的优点是插件部署方便,可以直接借原插件的壳,而不需要重新发布emq的整个release,缺点是代码修改很费时间,也不一定能切割出所有功能。

    方案二的优点是编码简单,缺点是需要重新打包整个镜像。主要的挑战在于快速打包发布镜像。

    实现路线

    1. 了解erlang基本语法,完成helloworld
    2. 编译运行EMQ的插件模板,尝试简单的修改
    3. 学习使用erlang的http库
    4. 在插件中加入http请求代码
    5. 完成简单的全流程
    6. 加入上下线hook
    7. 完成插件的config配置
    8. 整理代码,打包成独立插件并发布源码

    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里一个示例,很难搞清楚用法。

     

  • 相关阅读:
    数据量过大时数据库操作的处理
    VC中回调函数的用法
    基于BindingSource的WinForm开发
    VC获取各类指针
    GetSystemMetrics()函数的用法
    samba建立个人专享网盘
    Windows 7下用Windows照片查看器打开图片速度变慢的解决方案
    这是一个模板
    QT中编译和使用OPENCV
    MFC日志(2011.4.9)
  • 原文地址:https://www.cnblogs.com/bforever/p/10490403.html
Copyright © 2011-2022 走看看