Mqtt 连接为 aws IOT 预签名提供 403 URL
Mqtt connection gives 403 for aws IOT Pre-Signed URL
我有生成 IOT websocket URL 的 aws lambda 函数,如下所示。
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 并尝试按如下方式连接网络套接字。
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
我们的团队最近也 运行 解决了这个问题。
版本 > 1.2.0 的 aws-signature-v4
模块中的问题。
这是一个code:
`options.sessionToken = options.sessionToken || process.env.AWS_SESSION_TOKEN;`
默认情况下,AWS lambda 在 process.env
中有一个 AWS_SESSION_TOKEN
您应该使用 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
}
我有生成 IOT websocket URL 的 aws lambda 函数,如下所示。
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 并尝试按如下方式连接网络套接字。
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
我们的团队最近也 运行 解决了这个问题。
版本 > 1.2.0 的 aws-signature-v4
模块中的问题。
这是一个code:
`options.sessionToken = options.sessionToken || process.env.AWS_SESSION_TOKEN;`
默认情况下,AWS lambda 在 process.env
AWS_SESSION_TOKEN
您应该使用 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
}