提问者:小点点

如何在nodejs中生成aws s3签名


我一直在尝试用普通javascript生成用于上传对象的预签名url,但我经常遇到SignatureDon'tMatch错误。 如果有人能帮我,那将是很大的帮助。

      const myBucket = "my-bucket-name";
      const accessKey = "myaccesskey";
      const secretAccessKey = "mysecretkey";
      const regionName = "us-east-1";
      const myKey = "codeTest.jpg";
      const serviceName = "s3upload";
      const signedUrlExpireSeconds = 60 * 5; // In 5 minutes

      const ep = new AWS.Endpoint("s3.wasabisys.com");
      const s3 = new AWS.S3({
        accessKeyId: accessKey,
        secretAccessKey: secretAccessKey,
        bucket: myBucket,
        signatureVersion: "v4",
        region: regionName,
        endpoint: ep
      });
      const signedUrl = s3.getSignedUrl("putObject", {
            Bucket: myBucket,
            Key: myKey,
            ACL: "public-read",         
            Expires: signedUrlExpireSeconds,
      });


共2个答案

匿名用户

您不需要区域,因为AWS3是全球可用的。 还要仔细检查以下内容:

  1. 您的桶访问策略。
  2. 您通过API密钥获得的存储桶权限。
  3. 您的API密钥和机密。
  4. 您的存储桶名称和密钥
var AWS = require('aws-sdk');

const myBucket = "my-bucket-name";
const accessKey = "myaccesskey";
const secretAccessKey = "mysecretkey";
const myKey = "codeTest.jpg";
const signedUrlExpireSeconds = 60 * 5; // In 5 minutes

AWS.config.update({
    accessKeyId: accessKey,
    secretAccessKey: secretAccessKey
});

var s3 = new AWS.S3({
    endpoint: new AWS.Endpoint('https://s3.wasabisys.com'),
    s3ForcePathStyle: true //prevent an SSL certificate error
});

var params = {
    Bucket: myBucket, Key: myKey, Expires: signedUrlExpireSeconds
};

//Download URL
var url = s3.getSignedUrl('getObject', params);
    console.log('The URL is', url); // expires in 60 seconds
};

//Upload URL
s3.getSignedUrl('putObject', params, function (err, url) {
    console.log(err, url);
});

匿名用户

函数创建指向putObject到S3的预签名url。 这来自NodeJS/Express服务器。

函数createPresignedPost

    const S3 = require('aws-sdk/clients/s3');        
    const s3 = new S3(); //or new S3(config.aws.access), if you want to pass credentials

    module.exports.createPresignedPost = async function(remoteFile, expireSeconds = 180) {
        const params = {
            Bucket: S3_BUCKET_NAME,
            Fields: {
                key: remoteFile //This is S3 file name, where it will get uploaded
            },
            Expires: expireSeconds,
            Conditions: [
                {'acl': 'private'},
                ["content-length-range", 0, 20971520],      //20 MB
                ["starts-with", "$Content-Type", "image/"]  //only images
           ]
        };

        return new Promise((resolve, reject) => {
            s3.createPresignedPost(params, (err, data) => {
                if(err) {
                    return reject(err);
                }
            
                resolve(data);
            });
        })
    }

如果将此函数用作

const signed = await createPresignedPost("uploaded/file");

const body = {
    upload_url: signed.url,
    upload_fields: Object.assign({acl: 'private'}, signed.fields)
};
return res.status(ht.C.OK).send({success: true, data: body});

和@客户端,

ApiService.imagePost(item._id).then(response =>  {
      signed = response.data.data;
      const formData = new FormData();
      if (files.length > 0) {
          for(const field in signed.upload_fields) {
              formData.append(field, signed.upload_fields[field]);
          }
          formData.append("Content-Type",files[0].type);
          formData.append("file",files[0]);
                
          return ApiService.file.upload(signed.upload_url, formData);
      }
}