2

我的本地机器上有一个 NodeJS 应用程序。我正在尝试使用 Amazon S3 服务对其进行设置,但不幸的是,它不起作用。我能够获得签名的 URL,但是在上传文件时,AWS 返回 Forbidden 403(它多次断开连接,但在我从 CORS 中删除超时选项后停止)

到目前为止我做了什么:

  1. 使用休闲策略创建了新用户:

    {
    "Statement": [
       {
        "Action": "s3:*",
        "Effect": "Allow",
        "Resource": [
            "arn:aws:s3:::my-bucket",
            "arn:aws:s3:::my-bucket/*"
        ]
      }
     ]
    }
    
  2. 为该用户创建了新的访问密钥

  3. 将存储桶的 CORS 更新为

    <?xml version="1.0" encoding="UTF-8"?>
    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
        <CORSRule>
            <AllowedOrigin>*</AllowedOrigin>
            <AllowedMethod>GET</AllowedMethod>
            <AllowedMethod>PUT</AllowedMethod>
            <AllowedMethod>POST</AllowedMethod>
            <AllowedHeader>*</AllowedHeader>
        </CORSRule>
    </CORSConfiguration>
    
  4. 更新了存储桶策略

     {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "111",
                "Effect": "Allow",
                "Principal": {
                        "AWS": "my-user-id-number"
                },
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::my-bucket/*"
            }
        ]
    }
    
  5. 在 NodeJS 中创建调用以签名 url(使用 Express)

    aws.config.accessKeyId = process.env.AWS_ACCESS_KEY_ID;
    aws.config.secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
    
    router.get('/sign-s3', function (req, res) {
    
            var s3 = new aws.S3();
            var fileName = req.query.fileName;
            var fileType = req.query.fileType;
    
            var s3Params = {
                Key: fileName,
                Bucket: process.env.S3_BUCKET_NAME,
                Expires: 600,
                ContentType: fileType,
                ACL: 'public-read'
            };
            s3.getSignedUrl('putObject', s3Params, function (err, data) {
                if (err) {
                    console.log(err);
                    return res.end();
                }
                var returnData = {
                    signedRequest: data,
                    url: 'https://${S3_BUCKET_NAME}.s3.amazonaws.com/${fileName}'
                };
                res.write(JSON.stringify(returnData));
                res.end();
            });
        });
    
  6. 上传文件

    $http({
        method: 'GET',
        url: '/aws/sign-s3',
        params: data
    }).then(function (response) {
        var fd = new FormData();
        fd.append("file", file);
        $http({
            method: 'PUT',
            url: response.data.signedRequest,
            data: fd
        }).then(function (response) {
            defer.resolve(response);
        }, function (err) {
            defer.reject(err);
        });
    }, function (err) {
        defer.reject(err);
    });
    

还有一件事我不明白:我创建了一个用户并授予它对 s3 的访问权限,但我无法将用户分配给存储桶中的存储桶权限。访问策略中是否缺少某些内容?

提前感谢您的任何提示!

4

1 回答 1

0

I have figured out.

First of all, I generated new access keys to make sure these are correct. Second, I updated my upload request, to set content-type and to serialise only file, instead of FormData with file.

So the upload request looks

$http({
   method: 'PUT',
   url: response.data.signedRequest,
   data: file,
   headers: {'Content-type': file.type}
}).then(function (response) {
    defer.resolve(response);
  }, function (err) {
    defer.reject(err);
});
于 2016-12-21T16:24:11.957 回答