How to set the Mqtt broker username/password by code

When using Mqtt node ,we usually set the broker's username and password by typing the value mannully like this:

However, now we need to calulate the mqtt username and password each time to link, so how to fill the username and password by code?

In the help text for the node it is explained what you can do with dynamic control

broker
For the "connect" action, this property can override any of the individual broker configuration settings, including:

  • broker
  • port
  • url - overrides broker/port to provide a complete connection url
  • username
  • password

If this property is set and the broker is already connected an error will be logged unless it has the force property set - in which case it will disconnect from the broker, apply the new settings and reconnect.

Thanks for your reply.Could you give some more specific details?

Mine is in english, I do not speak chinese. Keep it in english and I guess more people can help. This is how it looks in my Node-RED. I have version 3.0.2. I have not tried it but this is how it is described how it should work. Please try out

1 Like

Are you using an old version of node red?

My NR version is 3.0.2.

When I switch the language to English, the help view of mine exactly matches the one krambriw gave.
So I am working on how to set the variable by code now.

This is what I'm using on one of my projects to set the topic from two variables.

mqtt_topic_A
The 'change' node does all the work replacing text elements with variables.

The MQTT-Out node is left blank apart from the broker's IP address.

mqtt_topic_B

Oops - sorry. Just re-read your question and realised you are referring to username and password.
As @krambriw says, details can be found in the Help panel.

If the translation is out of date then that should probably be reported to someone.

We completely rely on contributions for translations. So if @magicfire is willing to raise a pull request to update the translations for this language, I will be happy to guide them in doing so.

In fact, there are a few open pull requests that are simply waiting a 2nd person to verify they are good - the work may already be done.

Thanks for your reply.
For now, I've found a solution. It's not perfect but works.

(1) Start flow, and automaticly calculate username and password, store them in the flow scope context.
(2) Delay 10 seconds and auto click an inject button, fill msg.broker.username and msg.broker.password using the flow scope context.Send the msg to mqtt node,and mqtt will be linked.
The code I tested OK here:

`[
    {
        "id": "5ba78a30ef86e5cb",
        "type": "tab",
        "label": "流程 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "b71141ced9e0913a",
        "type": "inject",
        "z": "5ba78a30ef86e5cb",
        "name": "",
        "props": [
            {
                "p": "deviceName",
                "v": "PN4800",
                "vt": "str"
            },
            {
                "p": "productID",
                "v": "26pcRfEfrlm",
                "vt": "str"
            },
            {
                "p": "devicePsk",
                "v": "mfi3dUa8n32ZHHhcS2hQzRVSmms=",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 110,
        "y": 120,
        "wires": [
            [
                "157201184b3751ef"
            ]
        ]
    },
    {
        "id": "157201184b3751ef",
        "type": "function",
        "z": "5ba78a30ef86e5cb",
        "name": "calculate username and password",
        "func": "// 下面为node引入方式,浏览器的话,使用对应的方式引入crypto-js库\n//const crypto = require('crypto-js')\nconst crypto = global.get('crypto');\n\n// 产生随机数的函数\nconst randomString = (len) => {\n    len = len || 32;\n    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n    var maxPos = chars.length;\n    var pwd = '';\n    for (let i = 0; i < len; i++) {\n        pwd += chars.charAt(Math.floor(Math.random() * maxPos));\n    }\n    return pwd;\n}\n// 需要产品id,设备名和设备密钥\nconst productID = msg.productID;\nconst deviceName = msg.deviceName;\nconst devicePsk = msg.devicePsk;\n\n// 1. 生成 connid 为一个随机字符串,方便后台定位问题\nconst connid = randomString(5);\n// 2. 生成过期时间,表示签名的过期时间,从纪元1970年1月1日 00:00:00 UTC 时间至今秒数的 UTF8 字符串\nconst expiry = Math.round(new Date().getTime() / 1000) + 3600 * 24;\n// 3. 生成 MQTT 的 clientid 部分, 格式为 ${productID}${devicename}\nconst clientId = productID + deviceName;\n// 4. 生成 MQTT 的 username 部分, 格式为 ${clientid};${sdkappid};${connid};${expiry}\nconst userName = `${clientId};12010126;${connid};${expiry}`;\n//5.  对 username 进行签名,生成token、根据物联网通信平台规则生成 password 字段\nconst rawKey = crypto.enc.Base64.parse(devicePsk);   \t// 对设备密钥进行base64解码\nconst token = crypto.HmacSHA256(userName, rawKey);\nconst password = token.toString(crypto.enc.Hex) + \";hmacsha256\";\nconsole.log(`userName:${userName}\\npassword:${password}`);\n\nmsg.clientId = clientId;\nmsg.userName = userName;\nmsg.passWord = password;\n\nflow.set(\"flowUserName\", userName);\nflow.set(\"flowPassWord\", password);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 340,
        "y": 120,
        "wires": [
            []
        ]
    },
    {
        "id": "2d011d01f70a8d9f",
        "type": "mqtt out",
        "z": "5ba78a30ef86e5cb",
        "name": "",
        "topic": "$thing/up/property/26pcRfEfrlm/PN4800",
        "qos": "0",
        "retain": "false",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "97de65ee17bd78a5",
        "x": 520,
        "y": 280,
        "wires": []
    },
    {
        "id": "4472a8bbc319b7cf",
        "type": "inject",
        "z": "5ba78a30ef86e5cb",
        "name": "connect",
        "props": [
            {
                "p": "broker.username",
                "v": "flowUserName",
                "vt": "flow"
            },
            {
                "p": "broker.password",
                "v": "flowPassWord",
                "vt": "flow"
            },
            {
                "p": "action",
                "v": "connect",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": "10",
        "topic": "",
        "x": 120,
        "y": 220,
        "wires": [
            [
                "2d011d01f70a8d9f"
            ]
        ]
    },
    {
        "id": "dbe81783ce3d0dd8",
        "type": "mqtt in",
        "z": "5ba78a30ef86e5cb",
        "name": "",
        "topic": "$thing/down/property/26pcRfEfrlm/PN4800",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "97de65ee17bd78a5",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 200,
        "y": 400,
        "wires": [
            [
                "ec32e6afa2abaab1"
            ]
        ]
    },
    {
        "id": "ec32e6afa2abaab1",
        "type": "debug",
        "z": "5ba78a30ef86e5cb",
        "name": "debug 13",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 600,
        "y": 400,
        "wires": []
    },
    {
        "id": "487d478bbacd4907",
        "type": "inject",
        "z": "5ba78a30ef86e5cb",
        "name": "disconnect",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "action",
                "v": "disconnect",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{                          \"method\": \"report\",                 \"clientToken\": \"afwegafeegfa\",        \"params\": {        \"k\":\"1\"     } }",
        "payloadType": "str",
        "x": 130,
        "y": 340,
        "wires": [
            [
                "2d011d01f70a8d9f"
            ]
        ]
    },
    {
        "id": "b44bba25c1564a9f",
        "type": "inject",
        "z": "5ba78a30ef86e5cb",
        "name": "upload",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{                          \"method\": \"report\",                 \"clientToken\": \"afwegafeegfa\",        \"params\": {        \"k\":\"1\"     } }",
        "payloadType": "str",
        "x": 110,
        "y": 280,
        "wires": [
            [
                "2d011d01f70a8d9f"
            ]
        ]
    },
    {
        "id": "03ca719a1670f3a5",
        "type": "comment",
        "z": "5ba78a30ef86e5cb",
        "name": "store in flowUserName and flowPassWord",
        "info": "",
        "x": 440,
        "y": 80,
        "wires": []
    },
    {
        "id": "97de65ee17bd78a5",
        "type": "mqtt-broker",
        "name": "",
        "broker": "http://42.193.250.251/",
        "port": "1883",
        "clientid": "26pcRfEfrlmPN4800",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]`

Can't you feed calc user name and password node straight into the MQTT node?

For sure, that should be working fine, something like changing the last section in the function node and connect it's output directly to the MQTT out node

msg.clientId = clientId;
msg.broker.userName = userName;
msg.broker.passWord = password;
msg.action = "connect";

;flow.set("flowUserName", userName);
;flow.set("flowPassWord", password);
return msg;

That's why it's not perfect for now. Please give me some hints.
problem:
I tried in the function node like this :
msg.broker.username = xxx
But there is a grammar error.

When I wrote in this way, the error occours.

Sorry, try this instead

msg.broker = {};
msg.clientId = clientId;
msg.broker.userName = userName;
msg.broker.passWord = password;
msg.action = "connect";

;flow.set("flowUserName", userName);
;flow.set("flowPassWord", password);
return msg;
1 Like

Nice, I tried your new code.It works.

Improved code here:

[
    {
        "id": "5ba78a30ef86e5cb",
        "type": "tab",
        "label": "流程 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "b71141ced9e0913a",
        "type": "inject",
        "z": "5ba78a30ef86e5cb",
        "name": "计算",
        "props": [
            {
                "p": "deviceName",
                "v": "PN4800",
                "vt": "str"
            },
            {
                "p": "productID",
                "v": "26pcRfEfrlm",
                "vt": "str"
            },
            {
                "p": "devicePsk",
                "v": "mfi3dUa8n32ZHHhcS2hQzRVSmms=",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": "2",
        "topic": "",
        "x": 110,
        "y": 200,
        "wires": [
            [
                "157201184b3751ef"
            ]
        ]
    },
    {
        "id": "157201184b3751ef",
        "type": "function",
        "z": "5ba78a30ef86e5cb",
        "name": "计算 username 和 password",
        "func": "// 下面为node引入方式,浏览器的话,使用对应的方式引入crypto-js库\n//const crypto = require('crypto-js')\nconst crypto = global.get('crypto');\n\n// 产生随机数的函数\nconst randomString = (len) => {\n    len = len || 32;\n    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n    var maxPos = chars.length;\n    var pwd = '';\n    for (let i = 0; i < len; i++) {\n        pwd += chars.charAt(Math.floor(Math.random() * maxPos));\n    }\n    return pwd;\n}\n// 需要产品id,设备名和设备密钥\nconst productID = msg.productID;\nconst deviceName = msg.deviceName;\nconst devicePsk = msg.devicePsk;\n\n// 1. 生成 connid 为一个随机字符串,方便后台定位问题\nconst connid = randomString(5);\n// 2. 生成过期时间,表示签名的过期时间,从纪元1970年1月1日 00:00:00 UTC 时间至今秒数的 UTF8 字符串\nconst expiry = Math.round(new Date().getTime() / 1000) + 3600 * 24;\n// 3. 生成 MQTT 的 clientid 部分, 格式为 ${productID}${devicename}\nconst clientId = productID + deviceName;\n// 4. 生成 MQTT 的 username 部分, 格式为 ${clientid};${sdkappid};${connid};${expiry}\nconst userName = `${clientId};12010126;${connid};${expiry}`;\n//5.  对 username 进行签名,生成token、根据物联网通信平台规则生成 password 字段\nconst rawKey = crypto.enc.Base64.parse(devicePsk);   \t// 对设备密钥进行base64解码\nconst token = crypto.HmacSHA256(userName, rawKey);\nconst password = token.toString(crypto.enc.Hex) + \";hmacsha256\";\nconsole.log(`userName:${userName}\\npassword:${password}`);\n\nmsg.broker = {};\nmsg.clientId = clientId;\nmsg.broker.username = userName;\nmsg.broker.password = password;\nmsg.action = \"connect\";\n\n//flow.set(\"flowUserName\", userName);\n//flow.set(\"flowPassWord\", password);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 300,
        "y": 200,
        "wires": [
            [
                "2d011d01f70a8d9f"
            ]
        ]
    },
    {
        "id": "2d011d01f70a8d9f",
        "type": "mqtt out",
        "z": "5ba78a30ef86e5cb",
        "name": "",
        "topic": "$thing/up/property/26pcRfEfrlm/PN4800",
        "qos": "0",
        "retain": "false",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "97de65ee17bd78a5",
        "x": 520,
        "y": 280,
        "wires": []
    },
    {
        "id": "dbe81783ce3d0dd8",
        "type": "mqtt in",
        "z": "5ba78a30ef86e5cb",
        "name": "",
        "topic": "$thing/down/property/26pcRfEfrlm/PN4800",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "97de65ee17bd78a5",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 200,
        "y": 440,
        "wires": [
            [
                "ec32e6afa2abaab1"
            ]
        ]
    },
    {
        "id": "ec32e6afa2abaab1",
        "type": "debug",
        "z": "5ba78a30ef86e5cb",
        "name": "debug 13",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 520,
        "y": 380,
        "wires": []
    },
    {
        "id": "487d478bbacd4907",
        "type": "inject",
        "z": "5ba78a30ef86e5cb",
        "name": "断开MQTT连接",
        "props": [
            {
                "p": "action",
                "v": "disconnect",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 140,
        "y": 340,
        "wires": [
            [
                "2d011d01f70a8d9f"
            ]
        ]
    },
    {
        "id": "b44bba25c1564a9f",
        "type": "inject",
        "z": "5ba78a30ef86e5cb",
        "name": "上传消息",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{                          \"method\": \"report\",                 \"clientToken\": \"afwegafeegfa\",        \"params\": {        \"k\":\"1\"     } }",
        "payloadType": "str",
        "x": 120,
        "y": 280,
        "wires": [
            [
                "2d011d01f70a8d9f"
            ]
        ]
    },
    {
        "id": "9fca47c9a310c0f1",
        "type": "comment",
        "z": "5ba78a30ef86e5cb",
        "name": "发布",
        "info": "",
        "x": 510,
        "y": 240,
        "wires": []
    },
    {
        "id": "c2d05093c9702f2b",
        "type": "comment",
        "z": "5ba78a30ef86e5cb",
        "name": "订阅",
        "info": "",
        "x": 90,
        "y": 400,
        "wires": []
    },
    {
        "id": "97de65ee17bd78a5",
        "type": "mqtt-broker",
        "name": "",
        "broker": "http://42.193.250.251/",
        "port": "1883",
        "clientid": "26pcRfEfrlmPN4800",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.