为什么我得到 GET 的"我们计算的请求签名与您提供的签名不匹配",而 OpenSearch 的 PUT 却没有?



我遵循本指南,使用Node.js(AWS SDK for JavaScript的第3版(将HTTP请求签名到Amazon OpenSearch服务。

当我复制确切的示例代码并导出我的授权用户的AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY时,添加项目的PUT index/type/id请求成功:

201 Created
Response body: {"_index":"products","_type":"_doc","_id":"2","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}

然而,当我将请求改为GET /_search端点时,我得到:

403 Forbidden
Response body: {"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."}

用户已获得针对索引的完全授权:

{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::**:user/aws-elasticbeanstalk-ec2-user"
},
"Action": "es:*",
"Resource": "arn:aws:es:ap-southeast-2:**:domain/mydomain/*"
},

如何更正我的签名?

这是我从上面链接修改的代码:

const { HttpRequest } = require('@aws-sdk/protocol-http')
const { defaultProvider } = require('@aws-sdk/credential-provider-node')
const { SignatureV4 } = require('@aws-sdk/signature-v4')
const { NodeHttpHandler } = require('@aws-sdk/node-http-handler')
const { Sha256 } = require('@aws-crypto/sha256-browser')
const region = ''
const domain = ''
const index = 'products'
const type = '_search'
const createBody = (query) => ({
query: {
multi_match: {
query,
type: 'phrase',
fields: [
'tags',
'name',
'category',
'maker'
]
}
},
highlight: {
pre_tags: [''],
post_tags: [''],
fields: {
tags: {},
name: {},
category: {},
maker: {}
}
}
})
searchIndex('sh').then(() => process.exit())
async function searchIndex (query) {
const request = new HttpRequest({
body: JSON.stringify(createBody(query)),
headers: {
'Content-Type': 'application/json',
host: domain
},
hostname: domain,
method: 'GET',
path: index + '/' + type
})
const signer = new SignatureV4({
credentials: defaultProvider(),
region: region,
service: 'es',
sha256: Sha256
})
const signedRequest = await signer.sign(request)
const client = new NodeHttpHandler()
const { response } = await client.handle(signedRequest)
console.log(response.statusCode + ' ' + response.body.statusMessage)
let responseBody = ''
return new Promise((resolve) => {
response.body.on('data', (chunk) => {
responseBody += chunk
})
response.body.on('end', () => {
console.log('Response body: ' + responseBody)
resolve(responseBody)
})
}, (error) => {
console.log('Error: ' + error)
})
}

我也有这个问题,使用相同的教程

阅读关于请求正文搜索的文档,我发现它的状态如下:

注意_search API接受请求主体的HTTP GET和POST搜索,但并非所有HTTP客户端都支持向GET请求。POST是更普遍的选择。

将我的方法更改为POST为我解决了问题

最新更新