S3签名与getSignedUrl服务器端节点

时间:2018-03-06 20:54:43

标签: angularjs node.js amazon-web-services typescript amazon-s3

我尝试使用angular4中预先签名的网址将视频文件放入我的广告素材。

节点:

let s3 = new AWS.S3();
      s3.config.update({
        accessKeyId: process.env.VIDEO_ACCESS_KEY,
        secretAccessKey: process.env.VIDEO_SECRET_KEY
      })
      let videoId = await Video.createVideo()
      let params = {
        ACL: "public-read",
        Bucket: process.env.BUCKET_NAME,
        ContentType: 'video/mp4',
        Expires: 100,
        Key: req.jwt.username+"/"+videoId,
      }
      return s3.getSignedUrl('putObject', params, function (err, url) {
        if(!err) {
          console.log(url);
          res.status(200);
          res.json({
            url: url,
            reference: `${process.env.BUCKET_NAME}/${req.jwt.username}/${videoId}`,
            acl: params.ACL,
            bucket: params.Bucket,
            key: params.Key,
            contentType: params.ContentType,
          });
        } else {
          console.log(err);
          res.status(400);
          res.json({
            message: "Something went wrong"
          })
        }
      });

这为我成功生成了一个网址,我尝试在前端的帖子请求中使用它。

角:

this.auth.fileUpload().subscribe((result) => {
        console.log(result["key"], result["acl"], result["bucket"], result["contentType"])
        if(!result["message"]) {
          let formData = new FormData();
          formData.append('file', file.files[0]);
          const httpOptions = {
            headers: new HttpHeaders({
              "Key": result["key"],
              "ACL": result["acl"],
              "Bucket": result["bucket"],
              "Content-Type": result["contentType"],
            })
          };
          this.http.post(result["url"], formData, httpOptions ).subscribe((response) => {
            console.log("response");
            console.log(response);
            let reference = `https://s3.amazonaws.com/${result["reference"]}`
            this.auth.makeVideo(result["reference"]).subscribe((result) => {
              console.log(result);
            });
          }, (error) => {
            console.log("error");
            console.log(error);
          })

但这会产生错误。

SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your key and signing method

这是我生成的网址

https://MY_BUCKET_HERE.s3.amazonaws.com/admin/87f314f1-9f2e-462e-84ff-25cba958ac50?AWSAccessKeyId=MY_ACCESS_KEY_HERE&Content-Type=video%2Fmp4&Expires=1520368428&Signature=Ks0wfzGyXmBTiAxGkHNgcYblpX8%3D&x-amz-acl=public-read

我很确定我只是犯了一个简单的错误,但我无法弄清楚我的生活。我需要对标题做些什么吗?我是否需要更改我为帖子阅读文件的方式?我已经得到了使用FormData的公共存储桶和没有标题的简单发布请求,但现在我正在使用策略和私有存储桶,我的理解要少得多。我做错了什么?

1 个答案:

答案 0 :(得分:0)

如果为PutObject生成预签名URL,则应使用HTTP PUT方法将文件上载到该预签名URL。 POST方法不起作用(它专为浏览器上传而设计)。

另外,在调用PUT时不要提供HTTP标头。它们应在生成预签名URL时提供,但在使用预签名URL时则不应提供。