无法通过 Cognito 身份验证的用户连接到 AWS IoT Core

时间:2021-04-27 14:37:08

标签: amazon-web-services aws-iot

我正在尝试关注 this example,但 websocket 连接一直失败。

以下是我的步骤(使用 CDK 的后端实现):

  1. 具有身份池和附加身份验证角色的 Cognito 用户池
  2. auth 角色添加了 AWSIoTDataAccess 策略
authRole.addManagedPolicy( iam.ManagedPolicy.fromAwsManagedPolicyName('AWSIoTDataAccess'));
  1. 在前端,我导入了 aws-sdk 和 aws-iot-device-sdk。用户登录后,我会通过
  2. 获取他的凭据
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
          IdentityPoolId: identityPoolId,
          Logins: { [providerKey]: jwtToken },
        });

我现在可以使用 AWS.config.credentials.accessKeyId、AWS.config.credentials.secretAccessKey、AWS.config.credentials.sessionToken、AWS.config.credentials.identityId

  1. 在 IoT Core 中,我创建了一个用于测试的默认策略,我希望将其附加到认知身份以便能够连接 mqtt 客户端
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect",
        "iot:Publish",
        "iot:Subscribe",
        "iot:Receive",
        "iot:GetThingShadow",
        "iot:UpdateThingShadow",
        "iot:DeleteThingShadow"
      ],
      "Resource": "*"
    }
  ]
}
  1. 我尝试了 2 种方法来附加此策略(我怀疑这是问题所在,因为我不知道如何检查认知身份是否已收到它)
  • 选项 1:在后端调用 Lambda 的 api,传入 AWS.config.credentials.identityId
var aws = require('aws-sdk');
const iot = new aws.Iot();
exports.handler = async function(event:any) {

 let data = JSON.parse(event.body)
 await iot.attachPolicy({ policyName: 'default', principal: data.identityId })
 return sendRes(201, {message: 'policy attached'});
}
  • 选项 2:尝试在前端加载 aws-sdk 并附加
 iot.attachPolicy({ policyName: 'default', principal: AWS.config.credentials.identityId })
  1. 有了这一切,我从 import AWSIoTData from 'aws-iot-device-sdk'
  2. 创建了一个设备
var mqttClient = AWSIoTData.device({
          region: 'eu-central-1,
          host: 'xxx-my-iot-core-endpoint',
          clientId: 'testxxx-' + (Math.floor((Math.random() * 100000) + 1)),
          protocol: 'wss',
          maximumReconnectTimeMs: 8000,
          debug: false,
        //  port: 443, //I had this on and off to no effect
          accessKeyId:'' ,
          secretKey: '',
          sessionToken: ''
        })

        mqttClient.updateWebSocketCredentials(
          AWS.config.credentials.accessKeyId, 
          AWS.config.credentials.secretAccessKey, 
          AWS.config.credentials.sessionToken
        );

        mqttClient.on('connect', function () {
          console.log('mqttClient connected')
          mqttClient.subscribe(currentlySubscribedTopic)
        })

整个过程永远不会进入连接步骤,因为 websocket 连接失败。 在控制台中,我可以看到 wss://xxxxxxxxxxx-ats.iot.eu-central-1.amazonaws.com/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=undefined%2F20210427%2Feu-central-1%2Fiotdevicegateway%2Faws4_request&X-Amz-Date=20210427T135809Z&X-Amz-SignedHeaders=host&X-Amz-Signature=...

所以我假设我还需要使用“aws-signature-v4”的请求。这就是我被卡住的地方。

我还参考了另一个示例,其中建议使用 Lambda 函数来获取这样的预签名 Url:

const url = v4.createPresignedURL(
          'GET', endpoint + ":443",'/mqtt', 'iotdevicegateway',
          crypto.createHash('sha256').update('', 'utf8').digest('hex'),
          {
              key: data.accessKeyId,
              secret: data.secretAccessKey,
              sessionToken: data.SessionToken,
              protocol: 'wss',
              region: 'eu-central-1',
          }
        );

我已设法获取该 url 并尝试将其用于 Paho 客户端 import Paho from 'paho-mqtt' 然后 var mqttClient = new Paho.Client(presignedurl, clientId);

这些都没有带来任何结果,所以我很感激任何建议。

0 个答案:

没有答案