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);
    });
    

理解できないことがもう 1 つあります。ユーザーを作成して 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 に答える