sclausen / ngx-mqtt

This library isn't just a wrapper around MQTT.js for angular. It uses observables and takes care of subscription handling and message routing.
https://sclausen.github.io/ngx-mqtt/
MIT License
186 stars 82 forks source link

How to connect to Iot Core AWS using ngx-mqtt 16.0.0 #234

Open matiasAS opened 1 year ago

matiasAS commented 1 year ago

Hello, I need to connect to IoT Core using Angular 16 and ngx-mqtt@16.0.0. I have tried all the methods. If I add 'protocolVersion:5' in the connection options, it returns the following error:

image

And without that option, the connection closes without connecting.

The connection options are as follows: connectionIotCore: IMqttServiceOptions = { hostname: 'xxxxxxxxxxxx-ats.iot.us-east-2.amazonaws.com', port: 443, protocol: 'wss', path: '/mqtt', protocolId: 'MQTT', protocolVersion: 5, clientId: localStorage.getItem('username') + '_' + uuidv4(), rejectUnauthorized: false, cert: `-----BEGIN CERTIFICATE-----

        -----END CERTIFICATE-----`, 
key: `-----BEGIN RSA PRIVATE KEY-----

        -----END RSA PRIVATE KEY-----`, 
ca: `-----BEGIN CERTIFICATE-----

      -----END CERTIFICATE-----`, 

}

and environment is:

image

I need to solve this problem urgently. I have tried all the possible methods that have come to mind. I'm not sure if I need to do something in the AWS console, in the connection settings, or if the browser is simply not compatible with an SSL connection using the certificate. Please note that it is Ionic, but I am working on it as a web page. The reason for choosing Ionic instead of pure Angular is that I am still unsure if my app will also be a mobile app or not.

Any solution, observation, comment, question, etc., that you can provide, I will be attentive to it.

@sclausen can you help me please?

Regards.

sclausen commented 1 year ago

I'm really sorry, but it seems I can't help you. I've never worked with AWS IoT Core and after a brief research, I didn't found a solution for mqtt.js, but the recommendation to use AWS own SDK for that case. I would suggest you post this question on stackoverflow.com. There are probably more people who might have a solution.

matiasAS commented 1 year ago

@sclausen I have tried all the aws sdk libraries, and apparently they are compatible with javascript backend but not brower. That's why I ask how is the connection with ngx-mqtt since it is a very simple and easy to use library. At least with mosquitto with user/password authentication I can connect without problem, easy and fast.

I thought that by opening an issue on the github of the library there might be more direct help on a solution to my problem.

Can you keep the issue open in case someone else can help me?

sclausen commented 1 year ago

Having a look at one of the official examples I would assume it wouldn't be a big task to create ngx-aws-mqtt5 or something. I don't know if many would use that lib though…

Snappey commented 1 year ago

Did some digging into this, the library 100% works with AWS IoT Core using secure websockets. The most painful part was the authentication/authorisation, I ended up just using a custom lambda authorisor to make it work without dealing with certificates, but I don't see any reason why you wouldn't be able to use certs instead. (As pointed out below mqtt.js does not support certificate based authentication in the browser)

Angular Config:

export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
  hostname: '<my_aws_endpoint?.iot.<my_aws_region>.amazonaws.com',
  port: 443,
  protocol: "wss",
  path: '/mqtt',
  username: "<my_username>",
  password: "<my_password>",
  protocolVersion: 5,
};

Lambda Authoriser:

const connectPolicy = {
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "iot:Connect"
    ],
    "Resource": [
      "arn:aws:iot:*:*:client/*"
    ],
  }, {
    "Effect": "Allow",
    "Action": [
      "iot:Publish", "iot:Receive", "iot:Subscribe"
    ],
    "Resource": [
      "arn:aws:iot:*:*:topic/*"
    ]
  }, {
    "Effect": "Allow",
    "Action": [
      "iot:Subscribe"
    ],
    "Resource": [
      "arn:aws:iot:*:*:topicfilter/*"
    ]
  }, ]
};

exports.handler = async (event, context) => {
  const response = {
    isAuthenticated: false,
    principalId: "ExampleUpdateThis",
    disconnectAfterInSeconds: 86400,
    refreshAfterInSeconds: 300,
    policyDocuments: [connectPolicy]
  };

  if (!event.protocolData?.mqtt) {
    return response;
  }

  const { username, password, clientId } = event.protocolData.mqtt;
  if (username !== "<change__username>" || Buffer.from(password, "base64")
    .toString() !== "<change_password>") {
    return response;
  }

  return JSON.stringify({
    ...response,
    isAuthenticated: true
  });
};

Do not use this this in production; hardcoded credentials for authorisation with a single user and policy is an open door, this is purely a proof of concept.

Once you've setup the authoriser it's just the same as connecting to any password protected broker, change the username and password to one your authoriser expects and its "good to go". If you're having any issues following this I used this and followed their troubleshooting steps

The other trick I found was to set the default authoriser for my endpoint via the API (or CLI), can do so by using the following aws iot set-default-authorizer --authorizer-name <Authoriser_Name> or see here.

Could see this potentially causing some issues, IoT Core expects you to pass a header with the initial http upgrade request identifiying the authorisor to use if a default one is not set, I didn't dive into the details of the library so not sure if it's possible to attach custom headers to make that possible.

Long story short, library works with IoT Core just the authentication can be a pain point.

sclausen commented 1 year ago

Thanks for sharing an approach with other users of this library.

[…] but I don't see any reason why you wouldn't be able to use certs instead.

Unfortunately, mqtt.js doesn't support certificates in the browser, so I don't see them as a viable solution for the authorization problem.