![](/img/trans.png)
[英]What's a Django/Python solution for providing a one-time url for people to download files?
[英]How to generate a Django one-time download link
我想保护我的项目中的可下载文件,但不知道如何实现。 每次 post_detail 视图被调用时,都会生成一个新的下载链接,有效期为 60 分钟,并且也只能是访问链接。
模型.py
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(verbose_name="Post Title", max_length=25)
content = models.TextField(verbose_name="Post Content", max_length=5000)
tag = models.CharField(verbose_name="Tags/Meta - (sep. by comma)", max_length=50, blank=True)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, null=True)
postattachment = fields.FileField(
verbose_name="Post Attachment",
blank=True,
null=True,
upload_to=get_file_path_user_uploads,
validators=[file_extension_postattachment, file_size_postattachment]
published_date = models.DateField(auto_now_add=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
class Meta:
verbose_name = "Post"
verbose_name_plural = "Post(s)"
ordering = ['-title']
def __str__(self):
return self.title
视图.py
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
list_comments = Comment.objects.get_queryset().filter(post_id=pk).order_by('-pk')
paginator = Paginator(list_comments, 10)
page = request.GET.get('commentpage')
comments = paginator.get_page(page)
return render(request, 'MyProject/post_detail.html', {'post': post, 'comments': comments})
如果 smb。 也许有一些练习示例它会非常有帮助。
提前致谢
我不是 Django 专家,但我认为这是纯粹在 Django 中无法实现的。 一旦你的请求在 Django 中被执行,也就是说,你已经成功地为你的用户生成了一个下载链接,你不能在 60 分钟后返回并使其失效。 不是纯 Django(修复我!)。
另一个阻塞原因是 Django 根本就不是为提供文件而设计的。 文件(静态和媒体)旨在由您在 Django 前面的网络服务器(apache/nginx/etc...)提供服务。 例如,可以通过如下链接访问 Django 存储的文件: https://my-django-app.venom.com/media/my_file.jpg
: https://my-django-app.venom.com/media/my_file.jpg
这里的问题是,您的文件的位置很容易被猜到。 为了更难猜测,你应该把它放在一个随机长字符串的文件夹中,像这样: https://my-django-app.venom.com/media/b926yqagf6qrzpyew7h3kghtejayxp/my_file.jpg
: https://my-django-app.venom.com/media/b926yqagf6qrzpyew7h3kghtejayxp/my_file.jpg
。
为了实现这样的功能,我看到了两种方法(可能有几十种其他选择,但我立即想到了这两种):
要在 60 分钟后使路径无效,您必须按顺序对每个文件请求执行以下操作:
MEDIA
文件夹之外以提高安全性要实现第 6 步,您必须使用 Celery 扩展您的 Django 应用程序。 使用 Celery,您可以轻松安排作业(google for celery-beat
)。 此作业将每分钟执行一次(或您喜欢的任何时间),查询当前时间之后存储的 URL,并从文件系统上的MEDIA
文件夹中删除随机字符串文件夹及其内容。 Celery 超级简单,网上有几十个很好的例子。
通过将用户上传的内容存储在对象存储(例如 minio)中,可以非常轻松地在基础架构级别管理到期链接。 Minio 与 Amazon S3 非常相似,但它是开源的,可以托管在您自己的场所。 Minio 可以为存储的文件生成链接,您可以将过期时间设置在 1 分钟到 1 周之间。 在 Django 中,您所要做的就是从 minio 请求链接并指定到期时间。 其余的由 minio 管理。
要实现这种方法,您必须扩展 Django 的文件存储 API ( https://docs.djangoproject.com/en/2.1/ref/files/storage/ ) 并使用为 Django 编写的 minio 客户端之一。 我推荐 django-minio-storage ( https://github.com/py-pa/django-minio-storage )。
如果您采用这种方法,您可以将 Django 与用户上传的内容完全分离,并停止依赖您的网络服务器从 Django 的MEDIA
文件夹中提供文件。
祝你好运!
自从我上次更新以来,我已经创建了自己的 Django StorageBackend 实现来轻松地与 MinIO 交互。 我尽我所能保持这个库是最新的,但总是欢迎拉取请求: https : //github.com/theriveman/django-minio-backend
你可以查看这个 pypi 包django-onetimelink 。 它可以创建一个站点,其中包含所有上传文件的一次性链接。 它可用于从上传的文件生成一次性链接。
如果您需要一次性链接,
希望你明白了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.