Reputation: 4891
I keep getting back Connection refused: Not authorized
when trying to connect to the Azure IotHub using MQTT.js
(https://github.com/mqttjs/MQTT.js).
The SAS password is generated using Microsoft Device Explorer (https://github.com/Azure/azure-iot-sdk-csharp/tree/master/tools/DeviceExplorer) so providing the right read/write connection details along with an expiry date in the future, I am assuming it is correct and valid.
I am also requiring TLS/SSL to be enabled (as per Microsoft Azure documentation: https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support#tlsssl-configuration) via rejectUnauthorized: false
(as explained in the documentation for MQTT.js at https://github.com/mqttjs/MQTT.js#client).
How do I connect via Javascript using a 3rd party MQTT library and a SAS token?
This is a snippet of the Javascript code:
var MQTT = require("async-mqtt");
const deviceId = "<PUT_SOMETHING_HERE>";
const iotHubName = "<PUT_SOMETHING_HERE>";
const url = `${iotHubName}.azure-devices.net/${deviceId}/api-version=2016-11-14`;
const iotHubTopic = `devices/${deviceId}/messages/events/`
var client = MQTT.connect(`mqtts://${url}:8883`, {
username: url,
password: `SharedAccessSignature sr=${iotHubName}.azure-devices.net&sig=<COMBINATION_OF_PASSWORDS_URL_ENCODED>&se=<EPOCH_EXPIRY>&skn=<ACCESS_POLICY_NAME>`,
rejectUnauthorized: false, // https://github.com/mqttjs/MQTT.js#client
});
// this is code from the MQTT.js example, but I don't even reach it
async function doStuff() {
console.log("Starting");
try {
await client.publish(iotHubTopic, "It works!");
// This line doesn't run until the server responds to the publish
await client.end();
// This line doesn't run until the client has disconnected without error
console.log("Done");
} catch (e){
// Do something about it!
console.log("Error while sending a message...");
console.log(e.stack);
process.exit();
}
}
const ceremony = () => {
return new Promise((resolve, reject) => {
client.on("connect", doStuff);
return resolve();
})
.then((stuff) => {
console.log("Done?", stuff);
})
.catch((err) => {
console.log("Err...", err);
process.exit();
});
}
ceremony();
The output is this:
Done? undefined
events.js:183
throw er; // Unhandled 'error' event
^
Error: Connection refused: Not authorized
at MqttClient._handleConnack (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/lib/client.js:896:15)
at MqttClient._handlePacket (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/lib/client.js:332:12)
at work (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/lib/client.js:274:12)
at Writable.writable._write (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/lib/client.js:284:5)
at doWrite (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:428:64)
at writeOrBuffer (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:417:5)
at Writable.write (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:334:11)
at TLSSocket.ondata (_stream_readable.js:639:20)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
Upvotes: 2
Views: 4185
Reputation: 4432
Yes, Azure IoT Hub supports MQTT, you can use MQTT protocol to connect with the IoT Hub directly, and publish/subscribe the topics as send/receive messages with the documented topic names and topic filters. I have modified the above code, and it works fine.
var MQTT = require("async-mqtt");
const deviceId = "{the device name}";
const iotHubName = "{your iot hub name}";
const userName = `${iotHubName}.azure-devices.net/${deviceId}/api-version=2016-11-14`;
const iotHubTopic = `devices/${deviceId}/messages/events/`;
var client = MQTT.connect(`mqtts://${iotHubName}.azure-devices.net:8883`, {
keepalive: 10,
clientId: deviceId,
protocolId: 'MQTT',
clean: false,
protocolVersion: 4,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
username: userName,
password: "{SAS Token}",
rejectUnauthorized: false,
});
// this is code from the MQTT.js example, but I don't even reach it
async function doStuff() {
console.log("Starting");
try {
await client.publish(iotHubTopic, "It works!");
// This line doesn't run until the server responds to the publish
await client.end();
// This line doesn't run until the client has disconnected without error
console.log("Done");
} catch (e){
// Do something about it!
console.log("Error while sending a message...");
console.log(e.stack);
process.exit();
}
}
const ceremony = () => {
return new Promise((resolve, reject) => {
client.on("connect", doStuff);
return resolve();
})
.then((stuff) => {
console.log("Done?", stuff);
})
.catch((err) => {
console.log("Err...", err);
process.exit();
});
}
ceremony();
In the code, you need to note that:
See here for more details: Using the MQTT protocol directly (as a device)
Upvotes: 4
Reputation: 76
I was facing the same issue. After trying for half n hour, I came to know that one of my colleague had disabled my device on Iothub.😅
Upvotes: 0