为啥会提示“我们计算的请求签名与您提供的签名不匹配”。对于 GET 但不是 PUT 对于 OpenSearch?
Posted
技术标签:
【中文标题】为啥会提示“我们计算的请求签名与您提供的签名不匹配”。对于 GET 但不是 PUT 对于 OpenSearch?【英文标题】:Why do I get "The request signature we calculated does not match the signature you provided." for GET but not PUT for OpenSearch?为什么会提示“我们计算的请求签名与您提供的签名不匹配”。对于 GET 但不是 PUT 对于 OpenSearch? 【发布时间】:2021-12-20 10:50:55 【问题描述】:我正在关注 this guide 使用 Node.js(适用于 javascript 的 AWS 开发工具包的第 3 版)签署对 Amazon OpenSearch 服务的 HTTP 请求。
当我复制准确的示例代码并导出我的授权用户的AWS_ACCESS_KEY_ID
和AWS_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)
)
【问题讨论】:
@ErmiyaEskandary 我的 javascript linter 自动更改了这一点 - 对象属性名称上的引号不会影响请求,但感谢您的建议。 在错误块内 - 试试console.log(this.request.httpRequest); console.log(this.httpResponse);
,你会得到什么?
@ErmiyaEskandary 我添加了, (error) => console.log('here') console.log('Error: ' + error) )
,但它从不记录here
,它只记录前一个块(response.body.on('end'
)。我尝试记录您建议的一些变体,但它们都是undefined
。
【参考方案1】:
我也有这个问题,使用相同的教程
阅读docs on request body searches,我发现它声明如下:
注意 _search API 接受 HTTP GET 和 POST 请求正文 搜索,但并非所有 HTTP 客户端都支持将请求正文添加到 获取请求。 POST 是更通用的选择。
将我的方法更改为 POST
为我解决了问题
【讨论】:
以上是关于为啥会提示“我们计算的请求签名与您提供的签名不匹配”。对于 GET 但不是 PUT 对于 OpenSearch?的主要内容,如果未能解决你的问题,请参考以下文章
AWSSecretsManagerException:我们计算的请求签名与您提供的签名不匹配
我们计算的请求签名与您提供的签名不匹配。检查您的 AWS 秘密访问密钥和签名方法