亚马逊 S3,GET 请求被禁止?

Amazon S3, GET request forbidden?

我正在构建一个使用 Multer-s3 上传到亚马逊存储桶的 MEAN 堆栈应用程序。 它似乎可以完美地将图像上传到 Amazon-S3 中的存储桶以及数据库,但是当尝试从亚马逊获取图像时(使用 ng-repeat)它会出现以下错误:

GET https://s3-us-west-2.amazonaws.com/bucketfolder/bucketname/b40c4240-0417-11e6-9944-2d167e625d2b.jpg 403 (Forbidden)

在我的主控制器中:

function mainController(Upload, API, S3_BUCKET, TokenService, User, $timeout) {
  var self = this;
  self.usersClothing = [];

  self.uploadSingle = function() {
    Upload.upload({
      url: API + '/upload/single',
      data: { file: self.file, type: self.clothingType }
    })
    .then(function(res) {
        self.usersClothing = res.data.user.clothing.map(function(clothing) {
            clothing.image = S3_BUCKET + clothing.image;
            return clothing;
        });
    })
    .catch(function(err) {
      console.error(err);
    });
  }

我的 Angular 我上传图片的状态:

    <div ng-repeat="clothing in main.usersClothing">
        <img ng-src="{{clothing.image}}" class="clothing-img">
    </div>

修复了问题: 在我的亚马逊存储桶中,我更改了图像的首选项并将其设置为 public。然后它能够​​发出 GET 请求。

在您的上传代码片段 (POST) 中,您的代码正在服务器上执行,并且(我假设,您可以确认)使用 IAM 实例配置文件(角色)或访问密钥来访问您的 S3桶.

但是,您正在将 URL 从服务器传递给您的 S3 对象到客户端(浏览器)。是浏览器向 S3 发出对象的 GET 请求。浏览器没有您的 AWS 凭证。

选项 1

因此,为了让浏览器从 S3 存储桶下载对象,存储桶及其对象需要 public 以便无需身份验证即可下载。

  1. 授予 "List" 权限 "Everyone"。
  2. 给你的桶一个策略。

示例存储桶策略:

{
    "Version": "2008-10-17",
    "Id": "Policy1397495964002",
    "Statement": [
        {
            "Sid": "Stmt123",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::myBucketName/*"
        }
    ]
}

确保更改策略以替换您的真实存储桶名称。

这不需要您更改任何代码。

选项 2(首选)

但是,这意味着您的桶 public 面向世界。为避免这种情况,您应该生成一个预签名的 URL 供客户端使用。使用 s3.getSignedUrl 生成预签名的 URL 并将该 URL 传递给您的客户端以供下载。

这需要对您的服务器端代码进行一些代码更改。