我的mqtt协议和emqttd开源项目个人理解(14) - 使用redis插件来实现访问控制

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
访问控制,不限时长
简介: 我的mqtt协议和emqttd开源项目个人理解(14) - 使用redis插件来实现访问控制

一、工作环境准备


准备好redis server,http://blog.csdn.net/libaineu2004/article/details/76267836


erlang redis客户端使用开源项目,https://github.com/wooga/eredis


erlang连接池,https://github.com/emqtt/ecpool


emq使用的是v2.3.5版本,https://github.com/emqtt/emq-relx


我们以插件emq_auth_redis来实现,路径是/home/firecat/Prj/emq2.0/emq-relx-2.3.5/deps/emq_auth_redis


/home/firecat/Prj/emq2.0/emq-relx-2.3.5/data/loaded_plugins设置自启动插件


emq_recon. 
emq_modules. 
emq_retainer. 
emq_dashboard. 
emq_auth_redis.




二、redis数据准备


对照/home/firecat/Prj/emq2.0/emq-relx-2.3.5/deps/emq_auth_redis/README.md说明文档,往redis数据库写入username和password:


格式

HSET mqtt_user:<username> password "password"


命令

[root@localhost src]# ./redis-cli
127.0.0.1:6379> HSET mqtt_user:firecat password "123456"
(integer) 1
127.0.0.1:6379> HSET mqtt_user:lqh password "pass123"
(integer) 1
127.0.0.1:6379> HSET mqtt_user:firecatGTerm password "he2345v11t11"
(integer) 1
127.0.0.1:6379> hgetall mqtt_user
(empty list or set)
127.0.0.1:6379> HMGET mqtt_user:lqh password
1) "pass123"
127.0.0.1:6379> hgetall mqtt_user:lqh
1) "password"
2) "pass123"




源文件/home/firecat/Prj/emq2.0/emq-relx-2.3.5/deps/emqttd/src/emqttd_access_control.erl会启用校验


%% @doc Authenticate MQTT Client.
-spec(auth(Client :: mqtt_client(), Password :: password()) -> ok | {ok, boolean()} | {error, term()}).
auth(Client, Password) when is_record(Client, mqtt_client) ->
    auth(Client, Password, lookup_mods(auth)).
auth(_Client, _Password, []) ->
    case emqttd:env(allow_anonymous, false) of
        true  -> ok;
        false -> {error, "No auth module to check!"}
    end;
auth(Client, Password, [{Mod, State, _Seq} | Mods]) ->
    case catch Mod:check(Client, Password, State) of
        ok              -> ok;
        {ok, IsSuper}   -> {ok, IsSuper};
        ignore          -> auth(Client, Password, Mods);
        {error, Reason} -> {error, Reason};
        {'EXIT', Error} -> {error, Error}
    end.


源文件emq_auth_redis.erl,有校验的实施过程


check(Client, Password, #state{auth_cmd  = AuthCmd,

                              super_cmd = SuperCmd,

                              hash_type = HashType}) ->

   Result = case emq_auth_redis_cli:q(AuthCmd, Client) of


源文件emq_auth_redis_cli.erl,有redis的查询命令实现方法


%% Redis Query.

-spec(q(string(), mqtt_client()) -> {ok, undefined | binary() | list()} | {error, atom() | binary()}).

q(CmdStr, Client) ->

   io:format("1 CmdStr is: ~s  ~n", [CmdStr]),

   Cmd = string:tokens(replvar(CmdStr, Client), " "),

   io:format("2 Cms is: ~s  ~n", [Cmd]),

   ecpool:with_client(?APP, fun(C) -> eredis:q(C, Cmd) end).

ereids的使用案例,https://github.com/wooga/eredis


{ok, C} = eredis:start_link().

{ok, <<"OK">>} = eredis:q(C, ["SET", "foo", "bar"]).

{ok, <<"bar">>} = eredis:q(C, ["GET", "foo"]).

KeyValuePairs = ["key1", "value1", "key2", "value2", "key3", "value3"].

{ok, <<"OK">>} = eredis:q(C, ["MSET" | KeyValuePairs]).

{ok, Values} = eredis:q(C, ["MGET" | ["key1", "key2", "key3"]]).


string:tokens的用法可以参考erlang官方文档,http://erlang.org/doc/man/string.html


tokens(String, SeparatorList) -> Tokens

Types

String = SeparatorList = string()

Tokens = [Token :: nonempty_string()]

Returns a list of tokens in String, separated by the characters in SeparatorList.

Example:

> tokens("abc defxxghix jkl", "x ").

["abc", "def", "ghi", "jkl"]




三、除了emq_auth_redis_cli.erl上诉的查询方法,我们自己也可以实现其他查询方法:


-export([connect/1, q/2, q2/2]).
%% Redis Query.firecat add.
-spec(q2(string(), binary()) -> {ok, undefined | binary() | list()} | {error, atom() | binary()}).
q2(CmdStr, ClientId) ->
    io:format("3 CmdStr is: ~s  ~n", [CmdStr]),
    Cmd = string:tokens(replvar(CmdStr, "%c", ClientId), " "),
    io:format("4 Cms is: ~s  ~n", [Cmd]),
    ecpool:with_client(?APP, fun(C) -> eredis:q(C, Cmd) end).

这样,我在其他任意的erlang mod,都可以调用该方法,例如**.erl:


%%%% redis test
redis_test(ClientId) ->
   Result = case emq_auth_redis_cli:q2("HMGET mqtt_clientid:%c user group type", ClientId) of
                {ok, [undefined|_]} ->
                    io:format("clientid ignore: undefined  ~n"), %%firecat
                    {error, undefined};
                {ok, [User, Group, Type]} -> %%[undefined, undefined, undefined]
                    io:format("clientid is: ~s ~s ~s ~n", [User, Group, Type]),
                    ok;
                {error, Reason} ->
                    io:format("clientid error is: ~s  ~n", [Reason]),
                    {error, Reason}
             end,
   case Result of
             ok -> ok; %%firecat
             Error -> ok
             end.


四、redis插件除了可以检验username和password,还可以校验clientid的合法性。需要手动新增源文件emq_clientid_redis.erl。完整的源码请访问:


https://download.csdn.net/download/libaineu2004/10289890


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
网络协议 物联网 网络性能优化
物联网协议比较 MQTT CoAP RESTful/HTTP XMPP
【10月更文挑战第18天】本文介绍了物联网领域中四种主要的通信协议:MQTT、CoAP、RESTful/HTTP和XMPP,分别从其特点、应用场景及优缺点进行了详细对比,并提供了简单的示例代码。适合开发者根据具体需求选择合适的协议。
51 5
|
3月前
|
消息中间件 存储 传感器
RabbitMQ 在物联网 (IoT) 项目中的应用案例
【8月更文第28天】随着物联网技术的发展,越来越多的设备被连接到互联网上以收集和传输数据。这些设备可以是传感器、执行器或其他类型的硬件。为了有效地管理这些设备并处理它们产生的大量数据,需要一个可靠的消息传递系统。RabbitMQ 是一个流行的开源消息中间件,它提供了一种灵活的方式来处理和转发消息,非常适合用于物联网环境。
171 1
|
2月前
|
消息中间件 监控 物联网
MQTT协议对接及RabbitMQ的使用记录
通过合理对接MQTT协议并利用RabbitMQ的强大功能,可以构建一个高效、可靠的消息通信系统。无论是物联网设备间的通信还是微服务架构下的服务间消息传递,MQTT和RabbitMQ的组合都提供了一个强有力的解决方案。在实际应用中,应根据具体需求和环境进行适当的配置和优化,以发挥出这两个技术的最大效能。
181 0
|
3月前
|
物联网 C# 智能硬件
智能家居新篇章:WPF与物联网的智慧碰撞——通过MQTT协议连接与控制智能设备,打造现代科技生活的完美体验
【8月更文挑战第31天】物联网(IoT)技术的发展使智能家居设备成为现代家庭的一部分。通过物联网,家用电器和传感器可以互联互通,实现远程控制和状态监测等功能。本文将探讨如何在Windows Presentation Foundation(WPF)应用中集成物联网技术,通过具体示例代码展示其实现过程。文章首先介绍了MQTT协议及其在智能家居中的应用,并详细描述了使用Wi-Fi连接方式的原因。随后,通过安装Paho MQTT客户端库并创建MQTT客户端实例,演示了如何编写一个简单的WPF应用程序来控制智能灯泡。
121 0
|
3月前
|
物联网 网络性能优化 Python
"掌握MQTT协议,开启物联网通信新篇章——揭秘轻量级消息传输背后的力量!"
【8月更文挑战第21天】MQTT是一种轻量级的消息传输协议,以其低功耗、低带宽的特点在物联网和移动应用领域广泛应用。基于发布/订阅模型,MQTT支持三种服务质量级别,非常适合受限网络环境。本文详细阐述了MQTT的工作原理及特点,并提供了使用Python `paho-mqtt`库实现的发布与订阅示例代码,帮助读者快速掌握MQTT的应用技巧。
90 0
|
10天前
|
安全 网络安全 数据安全/隐私保护
访问控制列表(ACL)是网络安全中的一种重要机制,用于定义和管理对网络资源的访问权限
访问控制列表(ACL)是网络安全中的一种重要机制,用于定义和管理对网络资源的访问权限。它通过设置一系列规则,控制谁可以访问特定资源、在什么条件下访问以及可以执行哪些操作。ACL 可以应用于路由器、防火墙等设备,分为标准、扩展、基于时间和基于用户等多种类型,广泛用于企业网络和互联网中,以增强安全性和精细管理。
48 7
|
11天前
|
网络协议 安全 网络性能优化
了解访问控制列表 (ACL):概念、类型与应用
了解访问控制列表 (ACL):概念、类型与应用
26 2
|
13天前
|
网络虚拟化 数据安全/隐私保护 数据中心
对比了思科和华为网络设备的基本配置、接口配置、VLAN配置、路由配置、访问控制列表配置及其他重要命令
本文对比了思科和华为网络设备的基本配置、接口配置、VLAN配置、路由配置、访问控制列表配置及其他重要命令,帮助网络工程师更好地理解和使用这两个品牌的产品。通过详细对比,展示了两者的相似之处和差异,强调了持续学习的重要性。
26 2
|
1月前
|
网络协议 网络虚拟化 数据安全/隐私保护
访问控制列表(ACL)配置
访问控制列表(ACL)配置
访问控制列表(ACL)配置
|
1月前
|
网络协议 安全 网络安全
Cisco-命名ACL访问控制列表
Cisco-命名ACL访问控制列表
下一篇
无影云桌面