NodeJS AWS S3 -我们计算的请求签名与您提供的签名不匹配,请检查您的密钥和签名方法

gj3fmq9x  于 6个月前  发布在  Node.js
关注(0)|答案(5)|浏览(65)

我试图上传图片到s3与预先签署的网址从aws sdk生成。

router.get('/upload-url', async(req, res) => {
    try {

        AWS.config.update({
            secretAccessKey: process.env.AWS_SECRET_ACCESS,
            accessKeyId: process.env.AWS_ACCESS_KEY,
            region: 'ap-southeast-1'

        });

        const s3 = new AWS.S3();
        var params = { Bucket: process.env.bucket_name, Key: 'products', ContentType: 'image/jpeg' };
        s3.getSignedUrl('putObject', params, function(err, url) {
            if (err) {
                throw (err)
            }
            res.status(200).send({ link: url })
        })

    } catch (err) {
        res.status(400).send({ message: err.message })
    }
})

字符串
与上面的返回网址,它给给予一个错误,当我试图访问它

<Error>
<script class="__REQUESTLY__SCRIPT">(function(namespace) { window[namespace] = window[namespace] || {}; window[namespace].responseRules = {}; let open = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method) { this.addEventListener('readystatechange', function() { if (this.readyState === 4 && window[namespace].responseRules.hasOwnProperty(this.responseURL)) { const responseRule = window[namespace].responseRules[this.responseURL]; const {response, id} = responseRule; const responseType = this.responseType; let customResponse; customResponse = response.type === 'code' ? responseRule.evaluator({ method, url: this.responseURL, requestHeaders: this.requestHeaders, requestData: this.requestData, responseType: this.responseType, response: this.response }) : response.value; Object.defineProperty(this, 'response', { get: function () { if (response.type === 'static' && responseType === 'json') { return JSON.parse(customResponse); } return customResponse; } }); if (responseType === '' || responseType === 'text') { Object.defineProperty(this, 'responseText', { get: function () { return customResponse; } }); } window.postMessage({ from: 'requestly', type: 'response_rule_applied', id }, window.location.href); } }, false); open.apply(this, arguments); }; let send = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(data) { this.requestData = data; send.apply(this, arguments); }; let setRequestHeader = XMLHttpRequest.prototype.setRequestHeader; XMLHttpRequest.prototype.setRequestHeader = function(header, value) { this.requestHeaders = this.requestHeaders || {}; this.requestHeaders[header] = value; setRequestHeader.apply(this, arguments); } })('__REQUESTLY__')</script>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<AWSAccessKeyId>DHAWUIHDUIAWHDAWUI</AWSAccessKeyId>
<StringToSign>GET 1594960145 /bucketname/products</StringToSign>
<SignatureProvided>oD2y%2Ftv04ernxLiNdMAETiebi1KXY%3D</SignatureProvided>
<StringToSignBytes>47 45 54 0a 0a 0a 31 35 30 34 39 36 30 31 34 35 0a 2f 64 65 76 2e 6b 6f 6c 2e 73 68 6f 70 2f 70 70 6f 64 75 63 74 73</StringToSignBytes>
<RequestId>11A7BD415D04AAFE7E</RequestId>
<HostId>3zFeVQCbO+LraKZ7sR1j7rgMR9KdyOEqKFGX/5QCWXMhXLBubzre7Lb1eun/zATJU/xz69mpg+o=</HostId>
</Error>


我一直在寻找其他职位,但还没有找到解决方案。
我发现的一些建议是:

  • 不要在SECRET ACCESS KEY中包含“/”。(我的密钥不包含斜杠)
  • 不正确的凭据(我已经测试了与AWS的密钥,它的作品)
  • 更新存储桶权限和策略。(我已更新到所有访问策略)

我的bucket设置如下:
Bucket policy

{
    "Version": "2012-10-17",
    "Id": "Policy1594951813323",
    "Statement": [
        {
            "Sid": "Stmt15949510950",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<AccountNumber>:root"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::<bucketname>/*"
        }
    ]
}


CORS配置

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

稀释溶液

Use PUT Instead of POST for the pre-sign url to upload file to S3

svujldwt

svujldwt1#

我通过重新创建密钥对解决了这个问题。事实证明,我的密钥以等号“="开头。这不仅扰乱了下载的CSV,而且我猜这也扰乱了签名生成解析软件。重新生成密钥对使系统正常工作。

xam8gpfp

xam8gpfp2#

我不确定s3存储桶的策略,这是由我们的后端团队维护的。但是我可以使用postput方法将文件上传到我们的公共资产存储桶。

POST

生成预签名URL

response = s3.generate_presigned_post(Bucket=BUCKET,
                                        Key=KEY,
                                        ExpiresIn=3600)

字符串

使用预签名URL上传文件

signed_url_post = response['url']
data = response['fields']
key = response['key']

file_path = [YOUR_FILE_PATH]
with open(file_path, 'rb') as f:
    files = {'file': (file_path, f)}
    http_response = requests.post(url=signed_url_post, data=data, files=files)

PUT

生成预签名URL

url = s3.generate_presigned_url('put_object',
                             ExpiresIn=3600,
                             Params={"Bucket": BUCKET,
                             "Key": KEY,
                             "ContentType": "application/octet-stream"})

使用预签名URL上传文件

headers = {'content-type': 'application/octet-stream'}
with open(file_path_, 'rb') as f:
    http_response = requests.put(url=url, data=f, headers=headers)


如果使用put方法,请确保添加headers = {'content-type': 'application/octet-stream'}

jm81lzqq

jm81lzqq3#

在将Lambda functionsAPI Gateway一起使用时,有几件事需要考虑,
1.使用预签名URL时,请检查您的请求方法是PUT还是POST,应该是PUT
1.在AWS中检查您的lambda function,并确保ContentType与您上传的内容匹配。
1.确保您在请求中设置的headers与lambda.函数中的params匹配。

ibps3vxo

ibps3vxo4#

你只需要把signatureVersion放在你的构造函数中:

const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4',
});

字符串

sqserrrh

sqserrrh5#

当我遇到这个错误时,我意识到我正在使用的用户没有S3的必要权限。添加权限对我不起作用,所以我最终重新创建了一个具有这些权限的用户。我生成的新API Key和Secret成功工作。

相关问题