如何解决使用 Angular 2 使用预签名 URL 上传到 Amazon S3
在我的 Angular/Django Rest 框架中,我想将图片上传到 Amazon S3 存储桶。
我需要使用 Presigned URLs
,因为它比直接在客户端上传更快、更安全。
到目前为止,我设法创建并检索了预先签名的 URL,但我正在努力使用它来上传我的图片。
这是我在 Django 中用来创建 Presigned 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,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 :)"))
})
}
每当我想将名为“蝙蝠侠”的图片上传到名为“电影图片”的存储桶时,这是我的预签名 URL 的日志:
presigned_url:
fields:
AWSAccessKeyId: "AKIAYHDIXNIEPY2PQJ6V"
key: "batman"
policy: "eyJleHBpcmF0aW9uIjogIjIwMjEtMDctMDhUMTc6MTY6MTdaIiwgImNvbmRpdGlvbnMiOiBbeyJidWNrZXQiOiAibW92aWVwaWN0dXJlcyJ9LCB7ImtleSI6ICJiYXRtYW4ifV19"
signature: "pCjcs4TE1Qyj62v2KveCoMM1tXo="
__proto__: Object
url: "https://moviepictures.s3.amazonaws.com/"
以及上传到我的 Bucket 的服务:
uploadFile(r: any,selectedFile: any) {
return this.http.put(r['url'],r['fields'],selectedFile)
}
TypeError: 无法读取未定义的属性 'toLowerCase'
那么,使用我必须将图片上传到存储桶中的字段的正确方法是什么?
解决方法
在尝试修复我的代码但没有成功之后,我决定从 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")
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。