繁体   English   中英

使用 Django 从 Amazon S3 下载文件

[英]Download files from Amazon S3 with Django

我有一个 Django 应用程序,允许用户下载他们购买的 MP3 文件,这些 MP3 文件托管在 Amazon S3 中。 当用户单击“下载”按钮而不让他们看到原始链接(到亚马逊)时,我如何强制下载? 我有一个下载文件的视图,但文件已损坏。 这是它的样子:

def download(request):
    filename = 'https://s3-eu-west-1.amazonaws.com/skempi/Ihsahn/04-emancipation-qtxmp3.mp3'
    response = HttpResponse(mimetype='application/force-download')
    response['Content-Disposition']='attachment;filename="%s"'%filename
    response["X-Sendfile"] = filename
    return response

如果您不希望文件可下载,请将 ACL 设置为私有(只能通过您的帐户访问)。 如果您向用户提供签名 URL,您的用户仍然可以下载文件。 当您签署 URL 时,您会生成带有过期时间的令牌。 您可以将其设置为合理的值,例如 10 分钟。 使用适用于 Python 的 Amazon Web Services 接口 — Boto

import boto
conn = boto.connect_s3('<aws access key>', '<aws secret key>')
bucket = conn.get_bucket('your_bucket')
s3_file_path = bucket.get_key('path/to/file')
url = s3_file_path.generate_url(expires_in=600) # expiry time is in seconds

return HttpResponseRedirect(url)

请注意,这是安全的,因为令牌仅对一种请求方法(默认为 GET)且仅对一个文件有效。 因此,不存在有人重复使用令牌的风险,例如下载其他文件或操作给定的文件。

我无法轻易找到指定如何执行此操作的任何地方,并且在我搜索时一次又一次地回到这个问题。 所以

对于使用 boto 后端的 django-storages,执行此操作的方法类似于

filepath = settings.MEDIA_DIRECTORY + file.name
response_headers = {
    'response-content-type': 'application/force-download',
    'response-content-disposition':'attachment;filename="%s"'%file.name
    }
url = s3.generate_url(60, 'GET',
                bucket=settings.AWS_STORAGE_BUCKET_NAME,
                key=filepath,
                response_headers=response_headers,
                force_http=True)
return http.HttpResponseRedirect(url)

上面的答案已经过时,因为他们使用 boto 而不是 boto3。 这是用 boto3 完成的:

import boto3

client = boto3.client('s3', aws_access_key_id = config('AWS_ACCESS_KEY_ID'), /
aws_secret_access_key = config('AWS_SECRET_ACCESS_KEY'))
bucket_name = config('AWS_STORAGE_BUCKET_NAME')
file_name = settings.AWS_MEDIA_LOCATION + '/' + 'file-name'

url = client.generate_presigned_url(
                                    'get_object', 
                                    Params = { 
                                                'Bucket': bucket_name, 
                                                'Key': file_name, }, 
                                    ExpiresIn = 600, )
return HttpResponseRedirect(url)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM