简体   繁体   English

如何使用AWS IoT向/从Web浏览器发送/接收消息

[英]How to use AWS IoT to send/receive messages to/from Web Browser

We are trying to use Amazon Web Services Internet of Things (AWS IoT) to send messages from/to a Web Browser (eg: . Given that the AWS IoT supports JavaScript we expect that this is possible ... 我们正在尝试使用Amazon Web Services物联网(AWS IoT)从Web浏览器发送消息(例如:。鉴于AWS IoT支持JavaScript,我们希望这是可能的 ......

We have searched at the AWS IoT Documentation but only found server-side examples (which expose AWS secrets/keys...) 我们在AWS IoT文档中进行了搜索,但只查找了服务器端示例 (公开AWS秘密/密钥......)

Are there any good working examples or tutorials for using AWS IoT to send/receive messages via WebSockets/MQTT in the browser (eg: authenticating with AWS Cognito) ? 是否有任何好的工作示例或教程可以使用AWS IoT在浏览器中通过WebSockets / MQTT发送/接收消息(例如:使用AWS Cognito进行身份验证) Thanks! 谢谢!

Here's a sample that uses a cognito identity pool in JS to connect, publish and react to a subscription. 这是一个使用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);
        }

    };
}

Documentation for the credentials.get call, here 这里有credentials.get调用的文档

Remember to authorize your IAM role for subscribing / publishing as well. 请记住授权您的IAM角色进行订阅/发布。 Here's a sample: 这是一个示例:

{
    "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"
            ]
        }
    ]
}

In case anyone else is looking for a solution: here's a tutorial that demonstrates via a simple chat app how to get real-time updates into a ReactJS front-end using Serverless and Websockets on AWS IOT. 如果其他人正在寻找解决方案: 这是一个教程 ,通过一个简单的聊天应用程序演示如何使用AWS IOT上的无服务器和Websockets实时更新到ReactJS前端。 The source code of the tutorial is available on Github . Github上提供了本教程的源代码。

It is hard to find good tutorials for integrating AWS IoT in browser. 很难找到在浏览器中集成AWS IoT的好教程。

Basically you need to have some authentication method (Facebook, Google, AWS Cognito, your own SSO service with SAML support) and then you need to do following steps: 基本上您需要一些身份验证方法(Facebook,Google,AWS Cognito,您自己的SSO服务以及SAML支持),然后您需要执行以下步骤:

  1. Configure Cognito User Pool or Federated Identity Pool with your authentication method. 使用您的身份验证方法配置Cognito用户池或联合身份池。
  2. In browser you have to implement Extended Flow ( https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication-part-4-enhanced-flow/ ) 在浏览器中,您必须实现扩展流程( https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication-part-4-enhanced-flow/
  3. You need to AttachPolicy in IoT for your user's Cognito identityId - it will be used as principal (it the same way as devices are using certificates). 您需要在物联网中为您的用户的Cognito identityId添加AttachPolicy - 它将用作主体(它与设备使用证书的方式相同)。
  4. You need to create MQTT client using https://github.com/aws/aws-iot-device-sdk-js and providing your temporary accessKeyId , secretKey and sessionToken received from Extended Flow authentication. 您需要使用https://github.com/aws/aws-iot-device-sdk-js创建MQTT客户端,并提供从Extended Flow身份验证接收的临时accessKeyIdsecretKeysessionToken

It's very important to understand the difference between IAM policy and AWS IOT policy here. 在此处了解IAM策略与AWS IOT策略之间的区别非常重要。 Suppose you use cognito user pool as your identity provider. 假设您使用cognito user pool作为您的身份提供者。

First you need to set up a cognito identity pool , link the identity pool to your user pool and assign a role(attach IAM policy to this role) to this identity pool. 首先,您需要设置一个cognito identity pool ,将身份池链接到您的user pool并为此身份池分配一个角色(将IAM策略附加到此角色)。

Second, in your app, you first login so that you get the user pool credential, then you call 其次,在您的应用程序中,首先登录以便获得用户池凭据,然后进行调用

    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(),
      }
    });

to exchange your user pool credential with aws temporary access credential: 使用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()}`);
      });
    });

But the above code will not work!!! 但上面的代码将无法正常工作! Here is the tricky part: the credentials you get by exchanging your user pool credential is just a temporary credential that represent the AWS IAM policy you just attached to your identity pool! 这是一个棘手的部分:通过交换用户池凭据获得的凭据只是一个临时凭证,代表您刚刚附加到身份池的AWS IAM策略! When it requested to connect with your IOT, AWS will check if it's allowed to request and if it's allowed to do what the user requested. 当它请求与您的IOT连接时,AWS将检查是否允许其请求以及是否允许其执行用户请求的操作。 You already got the IAM policy so you are allowed to request, but it will check the AWS IOT policy attached to this identity. 您已获得IAM策略,因此您可以请求,但它将检查附加到此身份的AWS IOT策略。 Since you haven't done this, you are not allowed to do what you really requested(namely connection). 由于你还没有这样做,你不能做你真正要求的(即连接)。 So at the first time you want to connect, you should attach a IOT policy to this identity. 因此,在您第一次想要连接时,您应该将IOT策略附加到此身份。 You can do this either by command line or 您可以通过命令行或执行此操作

  (<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');
    });
  }

Now, when the identity tries to connect with IOT, IOT will find a IOT policy attached to this identity, and approve this connection. 现在,当身份尝试与IOT连接时,IOT将找到附加到此身份的IOT策略,并批准此连接。

Sorry about the bad wording. 对不好的措辞感到抱歉。 In summary, you need to clarify the difference between IAM policy and IOT policy. 总之,您需要阐明IAM策略和IOT策略之间的区别。 This is just what I understand, it may have incorrect places. 这正是我所理解的,它可能有不正确的地方。 If you find it, please leave a comment or edit my answer. 如果您找到它,请发表评论或编辑我的答案。

IMPORTANT Just found the relation between these two policies from official doc: https://docs.aws.amazon.com/iot/latest/developerguide/pub-sub-policy.html Look at section Policies for HTTP and WebSocket Clients 重要事项刚刚从官方文档中找到了这两个策略之间的关系: https//docs.aws.amazon.com/iot/latest/developerguide/pub-sub-policy.html查看HTTP和WebSocket客户端的策略部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM