Как использовать AWS IoT для отправки / получения сообщений в / из веб-браузера

Мы пытаемся использовать Amazon Web Services Internet of Things (AWS IoT) для отправки сообщений из / в веб-браузер (например:. Учитывая, что AWS IoT поддерживает JavaScript, мы ожидаем, что это возможно ...

Мы провели поиск в документации AWS IoT, но нашли только примеры на стороне сервера (которые раскрывают секреты / ключи AWS ...)

Есть ли хорошие рабочие примеры или руководства по использованию AWS IoT для отправки / получения сообщений через WebSockets / MQTT в браузере (например, аутентификация с помощью AWS Cognito)? Спасибо!


person Jack Carlisle    schedule 16.02.2016    source источник


Ответы (4)


Вот пример, в котором используется пул идентификаторов когнитивов в JS для подключения, публикации и реакции на подписку.

// Configure Cognito identity pool
AWS.config.region = 'us-east-1';
var credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'us-east-1:your identity pool guid',
});

// Getting AWS creds from Cognito is async, so we need to drive the rest of the mqtt client initialization in a callback
credentials.get(function(err) {
    if(err) {
        console.log(err);
        return;
    }
    var requestUrl = SigV4Utils.getSignedUrl('wss', 'data.iot.us-east-1.amazonaws.com', '/mqtt',
        'iotdevicegateway', 'us-east-1',
        credentials.accessKeyId, credentials.secretAccessKey, credentials.sessionToken);
    initClient(requestUrl);
});

function init() {
  // do setup stuff
}

// Connect the client, subscribe to the drawing topic, and publish a "hey I connected" message
function initClient(requestUrl) {
    var clientId = String(Math.random()).replace('.', '');
    var client = new Paho.MQTT.Client(requestUrl, clientId);
    var connectOptions = {
        onSuccess: function () {
            console.log('connected');

            // subscribe to the drawing
            client.subscribe("your/mqtt/topic");

            // publish a lifecycle event
            message = new Paho.MQTT.Message('{"id":"' + credentials.identityId + '"}');
            message.destinationName = 'your/mqtt/topic';
            console.log(message);
            client.send(message);
        },
        useSSL: true,
        timeout: 3,
        mqttVersion: 4,
        onFailure: function () {
            console.error('connect failed');
        }
    };
    client.connect(connectOptions);

    client.onMessageArrived = function (message) {

        try {
            console.log("msg arrived: " +  message.payloadString);
        } catch (e) {
            console.log("error! " + e);
        }

    };
}

Документация по вызову credentials.get здесь

Не забудьте также авторизовать свою роль IAM для подписки / публикации. Вот пример:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Receive",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Subscribe",
            "Resource": [
                "arn:aws:iot:us-east-1::your/mqtt/topic"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "iot:Publish",
            "Resource": [
                "arn:aws:iot:us-east-1::your/mqtt/topic"
            ]
        }
    ]
}
person Kyle Roche    schedule 17.02.2016
comment
функция sigv4 находится здесь для справки. - person Kyle Roche; 17.02.2016
comment
получаю следующую ошибку: aws-sdk-2.7.1.js: 6834 Uncaught Error: момент не определен (…) callListeners @ aws-sdk-2.7.1.js: 6834emit @ aws-sdk-2.7.1.js : 6810emit @ aws-sdk-2.7.1.js: 4054transition @ aws-sdk-2.7.1.js: 3831runTo @ aws-sdk -..... Так как я тоже обновил aws sdk, но все равно получаю то же самое ошибка, не могли бы вы мне помочь или, если возможно, поделитесь файлом aws-sdk.js, который вы используете. - person Bhavik Joshi; 16.11.2016
comment
вы использовали iotdevicegateway, что вы передаете в качестве параметра iotdevicegateway? Либо нам нужно передать resourceId, либо DeviceId? - person Bhavik Joshi; 16.11.2016
comment
Просто добавьте момент в свое приложение: npm i moment --save. Также iotdevicegateway остается в строковом формате. - person Georgii Oleinikov; 28.03.2017
comment
Просто из любопытства, нужно ли вам использовать что-то вроде this? Я вижу new Paho.MQTT.Client в коде, но не понимаю, откуда это - person Dan Esparza; 09.08.2017

Если кто-то еще ищет решение: вот руководство, демонстрирующее с помощью простого чат-приложения, как получать обновления в реальном времени в интерфейс ReactJS с помощью Serverless и Websockets на AWS IOT. Исходный код руководства доступен на Github.

person Chris    schedule 29.06.2017
comment
Этот пример не включает поддержку Cognito. Непонятно: предоставляет ли пример ключи в источнике javascript? - person Dan Esparza; 09.08.2017

Трудно найти хорошие руководства по интеграции AWS IoT в браузер.

В основном вам нужен какой-то метод аутентификации (Facebook, Google, AWS Cognito, ваша собственная служба SSO с поддержкой SAML), а затем вам необходимо выполнить следующие шаги:

  1. Настройте пул пользователей Cognito или пул федеративных удостоверений с использованием вашего метода аутентификации.
  2. В браузере необходимо реализовать расширенный поток (https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication-part-4-enhanced-flow/)
  3. Вам необходимо AttachPolicy в IoT для Cognito вашего пользователя identityId - он будет использоваться как основной (так же, как устройства используют сертификаты).
  4. Вам необходимо создать клиент MQTT, используя https://github.com/aws/aws-iot-device-sdk-js и предоставить ваши временные accessKeyId, secretKey и sessionToken, полученные в результате аутентификации расширенного потока.
person Maciej Dzikowicki    schedule 07.12.2018

Здесь очень важно понимать разницу между IAM политикой и AWS IOT политикой. Предположим, вы используете cognito user pool в качестве поставщика удостоверений.

Сначала вам нужно настроить cognito identity pool, связать пул удостоверений с вашим user pool и назначить роль (присоединить политику IAM к этой роли) этому пулу удостоверений.

Во-вторых, в своем приложении вы сначала входите в систему, чтобы получить учетные данные пула пользователей, а затем вызываете

    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
      IdentityPoolId: 'us-west-2:b8d2b32b-cbab-4ae3-9d47-1624d09c9350',
      Logins: {
        'cognito-idp.us-west-2.amazonaws.com/${userPoolIdentity}': userPoolCredential.getIdToken().getJwtToken(),
      }
    });

для обмена учетными данными пула пользователей с учетными данными временного доступа aws:

    AWS.config.getCredentials(e => {
      if(e) console.log("Get credential failed", e);
      this.device = AwsIot.device({//AwsIot is the aws-iot-sdk package
        clientId: clientID,//clientId is just random string
        host: '*-ats.iot.us-west-2.amazonaws.com',//replace * with your own host
        protocol: 'wss',
        accessKeyId: AWS.config.credentials.accessKeyId,
        secretKey: AWS.config.credentials.secretAccessKey,
        sessionToken: AWS.config.credentials.sessionToken
      });
      this.device.on('connect', function() {
        console.log("DEVICE CONNECTED");
      });
      this.device.subscribe('test');
      this.device
      .on('message', function(topic, payload) {
        console.log(`TOPIC IS ${topic}\nMESSAGE IS ${payload.toString()}`);
      });
    });

Но приведенный выше код работать не будет !!! Вот сложная часть: учетные данные, которые вы получаете при обмене учетными данными пула пользователей, - это просто временные учетные данные, которые представляют политику AWS IAM, которую вы только что подключили к своему пулу удостоверений! Когда он запросил соединение с вашим IOT, AWS проверит, разрешено ли ему запрашивать и разрешено ли делать то, что запрашивал пользователь. У вас уже есть IAM политика, поэтому вам разрешено запрашивать, но она проверит AWS IOT политику, прикрепленную к этому удостоверению. Поскольку вы этого не сделали, вам не разрешено делать то, что вы действительно просили (а именно, соединение). Поэтому в первый раз, когда вы хотите подключиться, вы должны прикрепить IOT политику к этому идентификатору. Вы можете сделать это либо из командной строки, либо

  (<AWS.CognitoIdentityCredentials>AWS.config.credentials).refresh(e => {
    if(e) console.log('error', e);
    const principal = (<AWS.CognitoIdentityCredentials>AWS.config.credentials).identityId;
    console.log(`IdentityId: ${principal}`);
    this.attachPrincipalPolicy("test-delete-after-use", principal);
  });
  attachPrincipalPolicy(policyName, principal) {
    new AWS.Iot().attachPrincipalPolicy({ 
      policyName: policyName, // you need to create policy beforehand in iot
      principal: principal 
    }, err => {
      err ? console.log('ATTACH PRINCIPAL POLICY ERROR', err) : console.log('ATTACH PRINCIPAL POLICY SUCCESS');
    });
  }

Теперь, когда удостоверение пытается подключиться к IOT, IOT обнаружит IOT политику, прикрепленную к этому удостоверению, и утвердит это соединение.

Извините за плохую формулировку. Таким образом, вам необходимо пояснить разницу между политикой IAM и политикой IOT. Это как раз то, что я понимаю, могут быть неправильные места. Если найдете, оставьте, пожалуйста, комментарий или отредактируйте мой ответ.

ВАЖНО Только что обнаружил связь между этими двумя политиками из официального документа: https://docs.aws.amazon.com/iot/latest/developerguide/pub-sub-policy.html. См. раздел Политики для клиентов HTTP и WebSocket < / сильный>

person xwa130    schedule 04.03.2019
comment
Я действительно хотел бы увидеть ваше полное решение этой проблемы, если бы это было возможно ?! Это как раз та проблема, с которой я столкнулся в настоящий момент. - person Ashkan Hovold; 27.04.2021