35

我们正在尝试使用亚马逊网络服务物联网 (AWS IoT) 从/向网络浏览器发送消息(例如:。鉴于 AWS IoT 支持 JavaScript,我们希望这是可能的......

我们在 AWS IoT 文档中进行了搜索,但只找到了服务器端示例 (暴露了 AWS 机密/密钥......)

是否有使用 AWS IoT 在浏览器中通过 WebSockets/MQTT 发送/接收消息的好的工作示例或教程(例如:使用 AWS Cognito 进行身份验证)?谢谢!

4

4 回答 4

27

这是一个在 JS 中使用 cognito 身份池来连接、发布和响应订阅的示例。

// 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"
            ]
        }
    ]
}
于 2016-02-17T12:14:06.063 回答
2

如果其他人正在寻找解决方案:这里有一个教程,通过一个简单的聊天应用程序演示如何使用 AWS IOT 上的无服务器和 Websockets 将实时更新到 ReactJS 前端。本教程的源代码可在 Github 上找到。

于 2017-06-29T18:57:09.960 回答
1

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 客户端的策略 部分

于 2019-03-04T17:22:36.980 回答
1

很难找到在浏览器中集成 AWS IoT 的好教程。

基本上,您需要有一些身份验证方法(Facebook、Google、AWS Cognito、您自己的支持 SAML 的 SSO 服务),然后您需要执行以下步骤:

  1. 使用您的身份验证方法配置 Cognito 用户池或联合身份池。
  2. 在浏览器中,您必须实现扩展流程(https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication-part-4-enhanced-flow/
  3. 您需要AttachPolicy在 IoT 中为您的用户的 Cognito identityId- 它将用作主体(它与设备使用证书的方式相同)。
  4. 您需要使用https://github.com/aws/aws-iot-device-sdk-js创建 MQTT 客户端并提供您的临时accessKeyIdsecretKeysessionToken从扩展流身份验证接收。
于 2018-12-07T12:14:49.740 回答