websocket - Mqtt 连接为 aws IOT 预签名 URL 提供 403

标签 websocket mqtt iot http-status-code-403 aws-iot

我有 aws lambda 函数,它可以生成如下的 IOT websocket URL。

const v4 = require('aws-signature-v4');
const crypto = require('crypto');

const WSSURL = v4.createPresignedURL(
        'GET',
        process.env.IOT_ENDPOINT_HOST.toLowerCase(),
        '/mqtt',
        'iotdevicegateway',
        crypto.createHash('sha256').update('', 'utf8').digest('hex'),
        {
            'key': process.env.IOT_ACCESS_KEY,
            'secret': process.env.IOT_SECRET_KEY,
            'protocol': 'wss',
            'region': process.env.IOT_AWS_REGION,
        }
    );

我在客户端有 mqttjs,它使用这个 url 并尝试如下连接 web socket。
var options = {
        will    : {
            topic  : LAST_WILL_TOPIC,
            payload: getMessageString(wss_userId, wss_email, wss_userType, {})
        },
        clientId: wss_userType + '||' + wss_userId
    };

    wssClient = mqtt.connect(WSSURL, options); 

此代码在几个月前运行良好,但现在连接未启动并出现以下错误
failed: Error during WebSocket handshake: Unexpected response code: 403

最佳答案

我们的团队最近也遇到了这个问题。
aws-signature-v4 中的问题版本 > 1.2.0 的模块。

这是 code :

`options.sessionToken = options.sessionToken || process.env.AWS_SESSION_TOKEN;` 

AWS lambda 默认有 AWS_SESSION_TOKENprocess.env
您应该使用 STS 承担角色并从中使用 sessionToken
import v4 from 'aws-signature-v4' // ^1.3.0
import STS from 'aws-sdk/clients/sts'

const { IOT_ENDPOINT_HOST, IOT_ROLE_ARN } = process.env
const sts = new STS()

const createSocketUrl = async () => {
  const data = await sts
    .assumeRole({
      RoleArn: IOT_ROLE_ARN,
      RoleSessionName: `some-role-session-name`,
      DurationSeconds: 3600
    })
    .promise()

  return v4.createPresignedURL(
    'GET',
    IOT_ENDPOINT_HOST,
    '/mqtt',
    'iotdevicegateway',
    '',
    {
      key: data.Credentials.AccessKeyId,
      secret: data.Credentials.SecretAccessKey,
      sessionToken: data.Credentials.SessionToken,
      protocol: 'wss'
    }
  )
}

或者如果您不想使用 STS
import v4 from 'aws-signature-v4' // ^1.3.0

const { IOT_ENDPOINT_HOST, IOT_ACCESS_KEY_ID, IOT_SECRET_ACCESS_KEY } = process.env

const createSocketUrl = () => {
  const { AWS_SESSION_TOKEN } = process.env

  delete process.env['AWS_SESSION_TOKEN']

  const url = v4.createPresignedURL(
    'GET',
    IOT_ENDPOINT_HOST,
    '/mqtt',
    'iotdevicegateway',
    '',
    {
      key: IOT_ACCESS_KEY_ID,
      secret: IOT_SECRET_ACCESS_KEY,
      protocol: 'wss'
    }
  )
  process.env['AWS_SESSION_TOKEN'] = AWS_SESSION_TOKEN

  return url
}

关于websocket - Mqtt 连接为 aws IOT 预签名 URL 提供 403,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51516052/

相关文章:

haskell - 无法将多个客户端与 Haskell Websocket 服务器一起使用

c++ - 如何从 MPU 陀螺仪发送的字节数组中获取整数

python - 导入错误 : cannot import name Pubnub

java - 使用 Java 中的 MQTT 将命令发布到 IBM IoT 中的设备

angularjs - 使用 Laravel 和 Latchet websocket 构建实时应用程序

python - Django Channels 或 Tornado 用于基于套接字的连接

javascript - 将视频从 HTML5 流式传输到 node.js

Azure 主题并通过 MQTT 发送消息

python - 如何在Python中没有client.subscribe()的情况下了解mqtt主题

c - Mosquitto - 订阅一个经纪人并使用 C 推送到另一个经纪人