我想保护我项目中的可下载文件,但不知道如何实现。 每次调用post_detail视图时,都会生成一个有效期为60分钟的新下载链接,该链接也只能是可访问的。
models.py
const string sqlErrorMessage = "MyCustomMessage";
var sqlException = FormatterServices.GetUninitializedObject(typeof(SqlException)) as SqlException;
var messageField = typeof(SqlException).GetField("_message", BindingFlags.NonPublic | BindingFlags.Instance);
messageField.SetValue(sqlException, sqlErrorMessage);
views.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
如果smb。也许有一些练习示例,将非常有帮助。
预先感谢
答案 0 :(得分:0)
我不是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/b926yqagf6qrzpyew7h3kghtejayxp/my_file.jpg
。
要实现这种功能,我看到了两种解决方法(可能还有很多其他选择,但我马上想到了这两种):
要使60分钟后路径无效,您必须按顺序对每个文件请求执行以下操作:
MEDIA
文件夹之外,以提高安全性要实现第六步,您必须使用Celery扩展Django应用程序。使用Celery,您可以轻松安排工作(Google为celery-beat
)。该作业将每分钟执行一次(或根据您的喜好执行),查询当前时间之后存储的URL,并从文件系统上MEDIA
文件夹中删除随机字符串文件夹及其内容。芹菜非常简单,在线上有很多很好的例子。
通过将用户上载的内容存储在对象存储(例如minio)中,在基础结构级别上管理到期链接非常容易。 Minio非常类似于Amazon S3,但是是开源的,可以在您自己的位置托管。 Minio可以为存储的文件生成链接,您可以在1分钟到1周之间设置到期时间。 在Django中,您所要做的就是从minio请求链接并指定到期时间。其余的由minio管理。
要实现此方法,您必须扩展Django的File Storage API(https://docs.djangoproject.com/en/2.1/ref/files/storage/)并利用为Django编写的微型客户端之一。我建议使用django-minio-storage(https://github.com/py-pa/django-minio-storage)。
如果采用这种方法,则可以使Django与用户上传的内容完全脱钩,并不再依赖网络服务器提供Django的MEDIA
文件夹中的文件。
祝你好运!
这是我在Django 2.x中基于软件包django-minio-storage
的minio存储后端的实现。我是在相对较长的时间之前创建的,它可能充满了不良做法和骇人听闻的解决方案。随时将其用作参考作品:https://gist.github.com/theriverman/db9025a22e0f3c40810bed5f12a139d8
答案 1 :(得分:0)
您可以检出此pypi软件包django-onetimelink。它可以创建一个包含所有上传文件的一次性链接的站点。而且它可以用来从上传的文件生成一次性链接。
答案 2 :(得分:0)
如果您需要一次性链接,
希望你有主意。