python - Django - 使用自定义的 login_required 装饰器保护 Apache 提供的媒体文件

标签 python django apache media login-required

我使用 Apache 部署了一个 Django 应用程序,并使用装饰器在大多数 View 中检查身份验证。

@custom_decorator
def myView(request):
    bla bla bla...

这不是 Django 自带的 @login_required 装饰器,但几乎是一样的,只是只允许某些组的用户访问。这按预期工作。

此外,我正在使用 Apache 提供媒体(用户上传的)文件,如下所示:

Alias /media /path/to/media
<Directory /path/to/media>
     Require all granted
</Directory

我可以很好地访问媒体文件,但问题是即使我没有登录,我也可以访问它们,只需手动输入网址,例如:

mySite/media/myFile.png

有没有办法限制对媒体文件的访问,希望使用自定义装饰器?

我偶然发现了一个类似的问题:How do you Require Login for Media Files in Django ,但不幸的是,这个答案超出了我的想象。

提前致谢!

最佳答案

当您提到 apache 的媒体路径时,这些文件直接由 Apache(或 Nginx 或任何其他 Web 服务器)提供服务。这些请求甚至不会通过您的 Django 应用程序。因此,您无法控制这些请求或它们提供的数据。

一种方法是创建单独的 API 来提供静态/媒体文件。在该 API 中,使用与其他内容相同的验证。

如果您有 AWS (Amazon Web Services) 就更好了或GCP (Google Cloud Platform)帐户,将静态文件存储在S3上或Cloud Storage分别并通过您的 API 提供文件的 URL。

PS:不要忘记从 Apache 配置中删除 media 路径。否则,Apache 将继续提供这些文件。


或者,如 Sarafeim's answer to Restricting access to private file downloads in Django 中所述这需要在服务器端和应用程序端进行修改。您需要一种方法让 HTTP 服务器询问应用程序服务器是否可以向请求该文件的特定用户提供文件。您可以使用 django-sendfile 来实现此目的它使用 X-SendFile 机制。根据django-sendfile 的自述文件:

This is a wrapper around web-server specific methods for sending files to web clients. This is useful when Django needs to check permissions associated files, but does not want to serve the actual bytes of the file itself. i.e. as serving large files is not what Django is made for.

要了解有关 sendfile 机制的更多信息,请阅读:Django - Understanding X-Sendfile

关于python - Django - 使用自定义的 login_required 装饰器保护 Apache 提供的媒体文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40697753/

相关文章:

python - Django 中的嵌套 View - Python

apache - 寻找 apache 构建选项

python - 将base64中的字符串转换为图像并保存在文件系统中

Python Pandas : Custom rolling window calculation

python - 使用多个关键字对象引用的 Django Rest Framework 对象

mysql - Django 从 MySQL 迁移到 Postgres

apache - OpenId 连接 : adding extra/custom parameter at the token endpoint call

mysql - 当 apache mysql 发生更改时触发 node.js

Python cx_Oracle 更新

python - 突然之间,需要进行什么样的转换才能改组(可能意味着一个新的阶段)?