上一篇隨筆我簡單的記錄了我對EMQ插件開發的了解過程,最后發現還是可以組合復用已有插件,因此這篇隨筆用於記錄使用的情況以及是否達到預期。
首先測試mysql認證插件的使用方式:
emqx_auth_mysql
根據readme,使用該插件需要先在數據庫上運行它們的sql腳本,在docker中完成這一步可以參考這篇文章。
主要的思想是,在Dockerfile中先用環境變量設置免密登錄,然后執行各個sql腳本(創建數據庫,數據表,插入數據),最后一個腳本創建用戶,設置權限和密碼。
將該插件的sql腳本執行后順便插入一個測試用的用戶:
INSERT INTO mqtt_user ( username,password ) VALUES ( "device1","device1" ); INSERT INTO mqtt_acl ( allow,username,access,topic ) VALUES ( 1,"device1",1,"a" ), ( 0,"device1",2,"a" ), ( 1,"device1",3,"b" );
根據插件的源碼,它會根據用戶名查詢數據庫,一共有六種可能:
- 數據庫存在該用戶,密碼未加鹽:
- 密碼正確,返回ok
- 密碼錯誤,返回error
- 數據庫存在該用戶,密碼加鹽:
- 密碼正確,返回ok
- 密碼錯誤,返回error
- 數據庫不存在該用戶,返回ignore(即沉默,交給其他插件處理,如果沒有其他插件,則會同意)
- 查詢錯誤(數據庫連接失敗),此時不通過任何請求(但是數據庫連接失敗時無法啟動插件,這種情況只會出現在建立連接后數據庫斷開的情況)
emqx_auth_http
這個插件同樣可以支持普通用戶認證,超級用戶認證和訪問權限控制,只需填寫對應服務的http接口即可,傳輸的內容都放在http包的body中(如果設置為post的話)或者url中(如果設置為get的話),收到的結果根據狀態碼和body分類,一共四種:
- 返回狀態碼200,但是body為"ignore",此時行為為ignore;
- 返回狀態碼200,body不是“ignore”,此時行為為ok;
- 返回狀態碼非200,此時行為為error;
- http請求失敗,此時返回error,不同意任何連接
另外還有超級用戶認證和訪問權限控制,他們都遵守以下規則:
- 同意:狀態碼200
- 否決:狀態碼非200
- 交給其他插件處理:狀態碼200,body為“ignore”
比較麻煩的一點是這兩個功能是關不掉的,因此如果不想使用該插件管理訪問權限和超級用戶認證,那就需要返回200和ignore
需求邏輯整理
目前的需求是,客戶端的密碼是加密過的,而且是需要認證服務器獲得之后驗證的,因此無法提前保存在數據庫,因此,mysql中不能保存相關用戶的密碼。
根據這兩個插件的行為,排除連接失敗和合並兩種數據庫的密碼驗證后,可以組合出9種行為,每種行為后方標記分別為:理論行為,需求行為
- mysql中有相關用戶
- mysql驗證通過
- http驗證通過: ok,ok
- http驗證失敗: error,error
- http驗證忽視: ok,ok
- mysql驗證失敗
- http驗證通過: ok,ok
- http驗證失敗: error,error
- http驗證忽視: error,error
- mysql驗證通過
- mysql中沒有相關用戶
- http驗證通過: ok,ok
- http驗證失敗: error,error
- http驗證忽視: ignore,ignore
經過列舉,我發現當mysql不保存用戶時,這兩個插件的行為完全符合我的需求,因此完全可以使用這兩個插件的組合來完成平台的認證和權限控制。其中mysql只負責權限控制,ignore用戶登錄,而http認證服務器只負責用戶登錄,ignore權限控制。
emqx_web_hook
webhook的概念很簡單,就是在各類hook點給預設的API發送數據,用以動態監控指定動作。這跟CPU上的調試用的埋點非常類似,GDB就是用這種思想監控程序的執行過程。
emq的webhook插件使用很簡單,只需要設置API的URL,再勾選要監控的動作即可,它硬編碼了要發送的格式,即在Body中發送json格式的文本,json中的內容也根據action硬編碼,無法配置,目前我們可以適應該接口,如果有需求,可以將其改成可配置的軟接口,也可以直接更改硬編碼的接口。