【问题标题】:Uploading to Amazon S3 with Angular 2 using presigned URLs使用 Angular 2 使用预签名 URL 上传到 Amazon S3
【发布时间】:2021-07-08 17:00:15
【问题描述】:

在我的 Angular/Django Rest Framework 中,我想将图片上传到 Amazon S3 存储桶。

我需要使用Presigned URLs,因为它比直接在客户端上传更快、更安全。

到目前为止,我设法创建并检索了预签名 URL,但我正在努力使用它来上传我的图片。

这是我在 Django 中用来创建预签名 URL 的视图:

class GenerateAwsSignature(View):

    def get(self, request, object_name):
        bucket_name = "moviepictures"
        presigned_url = create_presigned_url(bucket_name, object_name)        
        return JsonResponse({"presigned_url": presigned_url})


def create_presigned_url(bucket_name, object_name,
                         fields=None, conditions=None, expiration=3600):

    load_dotenv()
    AWS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID")
    AWS_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY")

    s3_client = boto3.client('s3',
                             aws_access_key_id=AWS_KEY_ID,
                             aws_secret_access_key=AWS_ACCESS_KEY)
    response = s3_client.generate_presigned_post(bucket_name,
                                                 object_name,
                                                 Fields=fields,
                                                 Conditions=conditions,
                                                 ExpiresIn=expiration)
    return response

我的组件:

onUpload() {
    const name = this.selectedFile.name
    this.s3Upload.getPresignedUrl(name)
      .subscribe(r => {
        console.log(r)
        this.s3Upload.uploadFile(r, this.selectedFile)
          .subscribe(r => console.log("uploaded :)"))
      })
  }

每当我想将名为“蝙蝠侠”的图片上传到名为“moviepictures”的存储桶中时,这是我的预签名 URL 的日志:

presigned_url:
fields:
AWSAccessKeyId: "AKIAYHDIXNIEPY2PQJ6V"
key: "batman"
policy: "eyJleHBpcmF0aW9uIjogIjIwMjEtMDctMDhUMTc6MTY6MTdaIiwgImNvbmRpdGlvbnMiOiBbeyJidWNrZXQiOiAibW92aWVwaWN0dXJlcyJ9LCB7ImtleSI6ICJiYXRtYW4ifV19"
signature: "pCjcs4TE1Qyj62v2KveCoMM1tXo="
__proto__: Object
url: "https://moviepictures.s3.amazonaws.com/"

以及上传到我的存储桶的服务:

uploadFile(r: any, selectedFile: any) {
    return this.http.put(r['url'], r['fields'], selectedFile)
  }

每当我想上传时,我都会收到此错误:

TypeError: 无法读取未定义的属性“toLowerCase”

那么使用我必须在我的存储桶中上传图片的字段的正确方法是什么?

【问题讨论】:

    标签: angular amazon-web-services amazon-s3 pre-signed-url


    【解决方案1】:

    在尝试修复我的代码失败后,我决定从s3_client.generate_presigned_post() 切换到s3_client.generate_presigned_url()。有关它们差异的更多信息,您可以查看此SO question。 基本上,您不会获得不同的字段,而是只会获得一个包含上传所需的所有内容的 url。 只是不要忘记添加"signature_version",最重要的是用您要上传的 MIME 类型的文件覆盖标题“content-type”。 在我的情况下,我将{'content-type': 'imge/jpeg'} 添加到我的标题中,因为默认情况下它将是'application/xml',我会收到SignatureDoesNotMatch 错误。

    这个方法在 Postman 中 100% 有效,所以我只需要在我的应用程序中实现它。

     my_config = Config(
            region_name='eu-west-3',
            signature_version='s3v4',
            retries = {
                'max_attempts': 10,
                'mode': 'standard'
            }
        )
    
    
    def create_presigned_url(bucket_name, object_name, expiration=3600):
    
        s3_client = boto3.client('s3',
                                aws_access_key_id="#########",
                                aws_secret_access_key="##########",
                                config=my_config)
        try:
            response = s3_client.generate_presigned_url('put_object',
                                                        Params={'Bucket': bucket_name ,
                                                                'Key': object_name,
                                                                "ContentType": "image/jpeg" },
                                                        ExpiresIn=expiration)
        except ClientError as e:
            logging.error(e)
            return None
    
        return response
    
    url = create_presigned_url("bemytest", "batman.jpg")
    

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 2017-02-15
      • 2020-10-23
      • 2021-08-26
      • 2014-11-17
      • 2016-10-12
      • 2020-09-30
      • 2018-12-27
      • 2016-07-12
      相关资源
      最近更新 更多