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

简介: 我的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


相关文章
|
9月前
|
消息中间件 人工智能 Apache
2025 OSCAR丨与创新者同频!Apache RocketMQ 邀您共赴开源之约
10 月 28 日,阿里云高级技术专家周礼分享如何基于 Apache RocketMQ 新特性构建异步化 Multi-Agent 系统。
291 58
|
消息中间件 运维 Serverless
商业版vs开源版:一图看懂云消息队列 RocketMQ 版核心优势
自建开源 RocketMQ 集群,为保证业务稳定性,往往需要按照业务请求的峰值去配置集群资源。云消息队列 RocketMQ 版 Serverless 实例通过资源快速伸缩,实现资源使用量与实际业务负载贴近,并按实际使用量计费,有效降低企业的运维压力和使用成本。
1062 127
|
NoSQL 安全 测试技术
Redis游戏积分排行榜项目中通义灵码的应用实战
Redis游戏积分排行榜项目中通义灵码的应用实战
549 4
|
消息中间件 存储 Apache
恭喜 Apache RocketMQ、Apache Seata 荣获 2024 开源创新榜单“年度开源项目”
近日,以“新纪天工、开物焕彩——致敬开源的力量”为活动主题的“重大科技成就发布会(首场)”在国家科技传播中心成功举办,并隆重揭晓了 2024 开源创新榜单,旨在致敬中国开源力量,传播推广开源科技成就,营造中国开源创新生态。2024 年开源创新榜单由中国科协科学技术传播中心、中国计算机学会、中国通信学会、中国科学院软件研究所共同主办,中国开发者社区承办,以王怀民院士为首组建评审委员会,进行研讨评审,面向中国开源行业领域,遴选具有创新性、贡献度和影响力的开源项目、社区、应用场景与开源事件。在评审出的 10 个年度开源项目中,Apache RocketMQ、Apache Seata 成功入选。
650 126
|
12月前
|
存储 缓存 NoSQL
Redis 核心知识与项目实践解析
本文围绕 Redis 展开,涵盖其在项目中的应用(热点数据缓存、存储业务数据、实现分布式锁)、基础数据类型(string 等 5 种)、持久化策略(RDB、AOF 及混合持久化)、过期策略(惰性 + 定期删除)、淘汰策略(8 种分类)。 还介绍了集群方案(主从复制、哨兵、Cluster 分片)及主从同步机制,分片集群数据存储的哈希槽算法。对比了 Redis 与 Memcached 的区别,说明了内存用完的情况及与 MySQL 数据一致性的保证方案。 此外,详解了缓存穿透、击穿、雪崩的概念及解决办法,如何保证 Redis 中是热点数据,Redis 分布式锁的实现及问题解决,以及项目中分布式锁
332 1
|
物联网 Linux 开发者
快速部署自己私有MQTT-Broker-下载安装到运行不到一分钟,快速简单且易于集成到自己项目中
本文给物联网开发的朋友推荐的是GMQT,让物联网开发者快速拥有合适自己的MQTT-Broker,本文从下载程序到安装部署手把手教大家安装用上私有化MQTT服务器。
2384 5
|
消息中间件 Apache 双11
Apache RocketMQ + “太乙” = 开源贡献新体验
Apache RocketMQ 是 Apache 顶级项目,源于阿里巴巴,历经多年双十一考验。RocketMQ 联合“太乙”平台启动开源竞赛,提供贡献价值评价与奖金激励(最高 5000 元),助力开发者成为社区核心成员。竞赛包含详尽教程与自动搭建环境,促进技术生态繁荣,推动分布式消息处理技术发展。欢迎加入,共创开源未来!
458 1
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
432 36
|
消息中间件 存储 Apache
恭喜 Apache RocketMQ 荣获 2024 开源创新榜单“年度开源项目”
恭喜 Apache RocketMQ 荣获 2024 开源创新榜单“年度开源项目”
380 1
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
1009 26