32

我在网站的用户注册部分的可下载 PDF 和电子表格中提供“敏感”信息。

有没有办法让 django 身份验证来保护这个媒体而不提供它(并且不必使用基本身份验证手动登录)?

我猜theres(手指交叉)不是用下面的伪代码来做到这一点的方法,但它有助于更​​好地说明最终目标。

#urls.py
(r'^protected_media/(?P<filename>.*)$', 'protected_media')

#views.py
from django.contrib.auth.decorators import login_required

@login_required
def protected_media(request, filename):
    # @login_required bounces you out to the login url
    # if logged in, serve "filename" from Apache
4

4 回答 4

11

在我看来,您在代码中概述的方法应该有效。它实际上与任何其他受保护资源没有什么不同:您的视图可以提供来自磁盘的文件、来自数据库的记录、呈现的模板或任何东西。就像 login_required 装饰器防止未经授权访问其他视图一样,它会阻止对您的视图提供受保护媒体的此类访问。

我在这里的问题中遗漏了什么吗?请澄清是否是这种情况。

编辑:关于您评论中的 django 文档链接:这是简单地从特定目录提供任何请求文件的方法。因此,在该示例中,类似/site_media/foo.jpg,的 URL/site_media/somefolder/bar.jpg将自动查找文件foo.jpgsomefolder/bar.jpgdocument_root. 基本上,下面的每一件事document_root都将是公开的。这显然是不安全的。所以你用你的方法来避免这种情况。

它也被认为是低效的,因为当您只需要像 Apache 这样的东西来获取 URL 请求并将其映射到硬盘驱动器上的文件时,django 只是增加了很多不必要的开销。(您不需要 django 会话、请求处理等)

在您的情况下,这可能不是一个大问题。首先,您已经保护了视图。其次,这取决于您的使用模式。您预计对这些文件有多少请求?您只使用 django 进行身份验证——这是否证明其他开销是合理的?如果没有,您可以考虑使用 Apache 提供这些文件并使用身份验证提供程序。有关这方面的更多信息,请参阅mod_wsgi文档:

mod_python我相信有类似的机制可用。(更新:刚刚注意到另一个答案。请参阅安德烈对该mod_python方法的回答。)

编辑 2:关于提供文件的代码,请参阅以下代码段:

send_file方法使用了一个 FileWrapper,它非常适合发送回大型静态文件(它不会将整个文件读入内存)。您需要content_type根据您发送的文件类型(pdf、jpg 等)更改 。

于 2009-07-11T20:47:38.377 回答
5

阅读这张Django 票以获取更多信息。从底部开始以节省一些时间。看起来它只是错过了进入 Django 1.2,我假设它也不在 1.3 中。

对于 Nginx,我发现了这个利用 X-Accel-Redirect 标头的Django 片段,但还没有尝试过。

于 2010-12-07T19:42:50.787 回答
3

如果我正确理解您的问题,您想限制对 Django 不提供的文件的访问,例如,使用 Apache 服务器?

然后你需要的是这个 Apache 服务器使用 Django 作为身份验证源的某种方式。

这个django 片段描述了这种方法。它在 Django 中创建一个访问处理程序,当对需要保护的静态文件的请求进入时,Apache 使用该处理程序:

<Location "/protected/location">
            PythonPath "['/path/to/proj/'] + sys.path"  
            PythonOption DJANGO_SETTINGS_MODULE myproj.settings
        PythonOption DjangoPermissionName '<permission.codename>'
        PythonAccessHandler my_proj.modpython #this should point to accesshandler
            SetHandler None
</Location>

希望这会有所帮助,该片段是不久前发布的,因此 Django 版本之间的情况可能有所不同:)

于 2009-07-11T21:28:57.060 回答
3

目前正在考虑通过 Django 更有效地提供静态文件作为 Google SOC 项目的一部分。对于 WSGI,如果可用,这将使用 WSGI 的 wsgi.file_wrapper 扩展,就像 mod_wsgi 一样,如果使用 mod_python,则使用 req.sendfile()。它还将支持返回诸如“Location”、“X-Accel-Redirect”等标头,不同的 Web 托管机制和代理前端接受这些标头作为提供静态文件的一种方式,其中位置由后端 Web 应用程序定义,它不如提供静态文件的前端那么有效。

我不确定 Django wiki 中是否有项目页面,但代码更改正在提交到 Django 源代码存储库的分支/soc2009/http-wsgi-improvements 分支。

你不需要严格地等待那些东西。它只是在不同的机制中放置一个干净且可移植的界面。如果在 Apache/mod_wsgi 前面使用 nginx 作为前端,您现在可以使用 X-Accel-Redirect。如果使用 Apache/mod_wsgi 3.0 和守护程序模式,您现在可以使用 Location,但需要确保正确设置 Apache。或者,您可以在 Django 应用程序周围实现您自己的 WSGI 中间件包装器,它会查找您自己的一些响应标头来指示要返回的文件,并使用 wsgi.file_wrapper 来返回它,而不是从 Django 返回的实际响应。

顺便说一句,其他人为 mod_python 和 mod_wsgi 列出的身份验证挂钩机制将使用 HTTP 基本身份验证,这不是您想要的。这是假设您希望文件受到基于 Django 表单的登录机制使用 cookie 和后端会话的保护。

于 2009-07-12T04:01:18.947 回答