node.js - “无法读取未定义的属性‘presigned-expires’”
问题描述
基本概述,我有一个运行 Node.js 应用程序的 AWS Lambda,它通过 http 调用将 JSON 发布到我的 AWS Elastic Search DB
所以,我从这个小错误开始:AWS: {"Message":"User: anonymous is not authorized to perform: es:ESHttpPost"}
经过大量时间后,我终于明白 AWS 不喜欢未签名的请求。
现在我坚持这个
Response:
{
"errorMessage": "Cannot read property 'presigned-expires' of undefined",
"errorType": "TypeError",
"stackTrace": [
"V4.isPresigned (/var/runtime/node_modules/aws-sdk/lib/signers/v4.js:206:32)",
"V4.addAuthorization (/var/runtime/node_modules/aws-sdk/lib/signers/v4.js:27:14)",
"Promise (/var/task/index.js:18:16)",
"new Promise (<anonymous>)",
"exports.handler (/var/task/index.js:6:12)"
]
}
在谷歌上的很多时间,甚至在网络上的更深入都没有给我这个问题的解决方案。
这是我的 lambda 代码:
var AWS = require('aws-sdk');
var creds = new AWS.EnvironmentCredentials('AWS');
var http = require('http');
exports.handler = async (event, context) => {
return new Promise((resolve, reject) => {
const options = {
hostname: 'XXX_ES_DOMAIN.eu-central-1.es.amazonaws.com',
path: '/path/1',
method: 'POST'
};
const req = http.request(options, (res) => {
resolve('Success');
});
var signer = new AWS.Signers.V4(req, 'es');
signer.addAuthorization(creds, new Date());
req.on('error', (e) => {
reject(e.message);
});
// send the request
req.write(JSON.stringify({ 'test': 'test' }));
req.end();
});
};
解决方案
您的请求中可能缺少标头,请参见下文。
var AWS = require('aws-sdk');
var path = require('path');
/* == Globals == */
var esDomain = {
region: 'us-east-1',
endpoint: 'my-domain-search-endpoint',
index: 'myindex',
doctype: 'mytype'
};
var endpoint = new AWS.Endpoint(esDomain.endpoint);
/*
* The AWS credentials are picked up from the environment.
* They belong to the IAM role assigned to the Lambda function.
* Since the ES requests are signed using these credentials,
* make sure to apply a policy that allows ES domain operations
* to the role.
*/
var creds = new AWS.EnvironmentCredentials('AWS');
/*
* Post the given document to Elasticsearch
*/
function postToES(doc, context) {
var req = new AWS.HttpRequest(endpoint);
req.method = 'POST';
req.path = path.join('/', esDomain.index, esDomain.doctype);
req.region = esDomain.region;
req.headers['presigned-expires'] = false;
req.headers['Host'] = endpoint.host;
req.body = doc;
var signer = new AWS.Signers.V4(req , 'es'); // es: service code
signer.addAuthorization(creds, new Date());
var send = new AWS.NodeHttpClient();
send.handleRequest(req, null, function(httpResp) {
var respBody = '';
httpResp.on('data', function (chunk) {
respBody += chunk;
});
httpResp.on('end', function (chunk) {
console.log('Response: ' + respBody);
context.succeed('Lambda added document ' + doc);
});
}, function(err) {
console.log('Error: ' + err);
context.fail('Lambda failed with error ' + err);
});
}
我从 github 项目 aws-samples amazon-elasticsearch-lambda-samples 中提取了这个: https ://github.com/aws-samples/amazon-elasticsearch-lambda-samples/blob/master/src/kinesis_lambda_es.js
推荐阅读
- c++ - 如何在 UnrealEngine 中对非 2 次幂纹理进行下采样?
- javascript - 抓取谷歌图片的网址:未定义
- html - 使用 ngFor 和 ngIf 隐藏元素
- aws-sdk - 使用 Cloudwatch Logs SDK 检索(发现的)字段列表
- php - 使用codeigniter时如何优化与数据库的连接
- c# - 按钮提交不适用于 HTTP 发布操作,已订阅剃须刀页面中的操作
- angular - 带有辅助路由的 Angular RouteReuseStrategy(仅重用主要部分)
- swift - 如何将 AVAudioEngine 的输出记录到 AAC 文件?
- css - 如何从我的网站上删除侧蓝线
- angular - 侧边栏图标在延迟加载中不可点击