0
votes

First I tried to use AWS Amplify library to use IOT Module to create AWS IOT Chat for my serverless application (I followed the steps given in the documentation), but it didn't work and gave 'Socket Already Closed' error.

Then I tried aws-iot-device-sdk and followed AWS documentation and code snippets to do so, but same error.

I have followed below steps:

  1. I have given "iot:*" rights to my Cognito pool.
  2. I have created one policy and attached my Cognito user identity to that policy.
  3. Then I tried connecting it using SDK and amplify library, and it was successfully connected, but then when I tried to publish/subscribe to a topic, it has thrown the same error.
1

1 Answers

1
votes

I'm not entierly sure where your issue might be, but I struggled with the same issue when I first started using Amplify PubSub. For me it was a policy issue. So one of this things might help:

Connect your thing policy document to the user identity for the federated pool (not the identity from the user pool). My policy document looks like this:

 {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect",
        "iot:AttachPrincipalPolicy",
        "iot:Publish",
        "iot:Subscribe",
        "iot:Receive",
        "iot:GetThingShadow",
        "iot:UpdateThingShadow",
        "iot:DeleteThingShadow"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

To attach/update the the policy for all my users (not so many) I use a Lambda function to do it:

var AWS = require("aws-sdk");
const cognito = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});
var cognitoidentity = new AWS.CognitoIdentity();
var iot = new AWS.Iot({apiVersion: '2015-05-28'});

exports.handler = (event, context, callback) => {
    var params = {
      IdentityPoolId: 'eu-central-1:xxxxxxxx-xxxx-xxxx-xxx-xxxxxxxx', /* change this */
      MaxResults: 50,
    };
    cognitoidentity.listIdentities(params, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
            addPolicies(data.Identities);
        }
    });
    function addPolicies(users) {
        for (let i = 0; i<users.length;i++) {
            var params2 = {
              policyName: 'myIOTPolicy',
              principal: users[i].IdentityId
            };
            iot.attachPrincipalPolicy(params2, function(err, data) {
              if (err) console.log(err, err.stack);
              else     console.log(data);
            });
        }
    }
  callback(null, event);
};

For my authenticated role in the identity pool, I have the following policy attached to the role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:AttachPrincipalPolicy",
                "iot:Connect",
                "iot:Publish",
                "iot:Subscribe",
                "iot:Receive",
                "iot:GetThingShadow",
                "iot:UpdateThingShadow",
                "iot:DeleteThingShadow"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

Hope this helps