使用AWS预签名URL进行PUT的应用程序是什么?

时间:2018-06-27 20:55:30

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

据我所知,预签名url是一种授予外部人员通过给定url进行操作的权限的方法,但是此url在形式上似乎非常严格。检查签名时的任何差异都可能导致403

对于下载而言,这很简单,但是对于上载呢?

假设我想生成一个将test.txt上传到testbucket的网址,我可以使用

s3.generate_presigned_url(ClientMethod='put_object', Params={'Bucket': 'testbucket', 'Key': 'test.txt'}, HttpMethod='PUT', ExpiresIn=120)

但是这样做会导致在调用url(requests.put(url))时我的存储桶中有一个空文件

我必须指定

之类的内容
with open(some_file, 'rb') as f:
    s3.generate_presigned_url(ClientMethod='put_object', Params={'Bucket': 'testbucket', 'Key': 'test.txt', 'Body': f.read()}, HttpMethod='PUT', ExpiresIn=120)

为了真正获得有意义的上载。

但这会否破坏目的?该URL应该发送给其他人使用。如果我已经知道有关文件的所有信息,包括其内容,那是否意味着我已经拥有文件了?如果它是一个未知文件,我只能得到一些信息,例如file_name,也许还有content-lengthcontent-type怎么办?

即使说我创建一个API端点并要求用户传入数据(我想包括其内容),然后生成供用户使用的url,我也可能会得到数据并直接上传,而不是通过预先签名的网址,对吧?

这是一笔交易。我想进行多部分上传时,看起来会变得更加复杂。我需要为该用户生成多个预签名的URL吗?我觉得这没有道理。有人可以教育我吗?

1 个答案:

答案 0 :(得分:2)

您不提供尸体。您提供存储桶和密钥,SDK为您提供了一个预签名的URL,并且您与客户端共享了该URL。然后,您的客户端将文件上传到该URL。您指定存储区和对象键,而客户端提供文件内容。

下面是一个如何为上传生成预签名URL的示例:

import boto3

s3 = boto3.client('s3')
print s3.generate_presigned_url('put_object', { 'Bucket': 'xxx', 'Key': 'yyy' }, 3600)

下面是一个如何上传到预先签名的URL的示例:

import requests

payload = 'fred'
url = <whatever previous script returned>
r = requests.put(url, data=payload)
r.raise_for_status()