apache 你如何要求在 Django 中登录媒体文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1114559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you Require Login for Media Files in Django
提问by TomFuertes
I'm serving "sensitive" information in downloadable PDF's and Spreadsheets within a user registration section of a site.
我在网站的用户注册部分提供可下载的 PDF 和电子表格中的“敏感”信息。
Is there a way to allow the django authentication to secure this media withoutserving it (and not have to manually login using basic auth)?
有没有办法允许 django 身份验证在不提供此媒体的情况下保护它(并且不必使用基本身份验证手动登录)?
I'm guessing theres (fingers crossed) nota way to do it with the psuedo code below, but it helps better illustrate the end goal.
我猜这里(手指交叉)不是用下面的伪代码来做的方法,但它有助于更好地说明最终目标。
#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
采纳答案by ars
It seems to me that the method you outlined in your code should work. It's really no different than any other protected resource: your views can serve files from disks, records from databases, rendered templates or anything. Just as the login_required decorator prevents unauthorized access to other views, it will prevent such access to your view serving protected media.
在我看来,您在代码中概述的方法应该可行。它确实与任何其他受保护资源没有什么不同:您的视图可以提供来自磁盘的文件、来自数据库的记录、呈现的模板或任何东西。正如 login_required 装饰器防止未经授权访问其他视图一样,它将防止对您的视图提供受保护媒体的此类访问。
Am I missing something from your question here? Please clarify if that's the case.
我在这里从你的问题中遗漏了什么吗?请澄清是否是这种情况。
EDIT: With regard to the django doc link in your comment: that's the method for simply serving any request file from a particular directory. So, in that example URLS like /site_media/foo.jpg, /site_media/somefolder/bar.jpgwill automatically look for files foo.jpgand somefolder/bar.jpgunder document_root. Basically, every thing under document_rootwill be publicly available. That's obviously insecure. So you avoid that with your method.
编辑:关于您评论中的 django doc 链接:这是简单地从特定目录提供任何请求文件的方法。因此,在该示例网址,喜欢/site_media/foo.jpg,/site_media/somefolder/bar.jpg会自动寻找文件foo.jpg和somefolder/bar.jpg下document_root。基本上,下面的所有内容document_root都将公开可用。这显然是不安全的。所以你用你的方法避免了这种情况。
It's also considered inefficient because django is just adding a lot of unnecessary overhead when all you need is something like Apache to take a URL request and map it to a file on the hard drive. (You don't need django sessions, request processing, etc.)
它也被认为是低效的,因为 django 只是增加了很多不必要的开销,而您只需要像 Apache 这样的东西来获取 URL 请求并将其映射到硬盘驱动器上的文件。(您不需要 django 会话、请求处理等)
In your case, this may not be such a big concern. First, you've secured the view. Second, it depends on your usage patterns. How many requests do you anticipate for these files? You're only using django for authentication -- does that justify other overhead? If not, you can look into serving those files with Apache and using an authentication provider. For more on this, see the mod_wsgidocumentation:
在您的情况下,这可能不是一个大问题。首先,您已经保护了视图。其次,这取决于您的使用模式。您预计会有多少对这些文件的请求?您只使用 django 进行身份验证——这是否证明其他开销是合理的?如果没有,您可以考虑使用 Apache 提供这些文件并使用身份验证提供程序。有关更多信息,请参阅mod_wsgi文档:
- http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms
- see the section "Apache Authentication Provider" and search for django
- http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms
- 请参阅“Apache Authentication Provider”部分并搜索 django
There are similar mechanisms available under mod_pythonI believe. (Update: just noticed the other answer. Please see Andre's answer for the mod_pythonmethod.)
mod_python我相信有类似的机制可用。(更新:刚刚注意到另一个答案。请参阅 Andre 对mod_python方法的回答。)
EDIT 2: With regard to the code for serving a file, please see this snippet:
编辑 2:关于提供文件的代码,请参阅以下代码段:
The send_filemethod uses a FileWrapper which is good for sending large static files back (it doesn't read the entire file into memory). You would need to change the content_typedepending on the type of file you're sending (pdf, jpg, etc).
该send_file方法使用 FileWrapper,它非常适合将大型静态文件发回(它不会将整个文件读入内存)。您需要content_type根据您发送的文件类型(pdf、jpg 等)更改。
回答by Dave
Read this Django ticketfor more info. Start at the bottom to save yourself some time. Looks like it just missed getting into Django 1.2, and I assume also isn't in 1.3.
阅读此Django 票证了解更多信息。从底部开始以节省一些时间。看起来它只是错过了进入 Django 1.2,我认为也不在 1.3 中。
For Nginx, I found this Django snippetthat takes advantage of the X-Accel-Redirect header, but haven't tried it yet.
对于 Nginx,我发现这个Django 片段利用了 X-Accel-Redirect 标头,但还没有尝试过。
回答by Graham Dumpleton
More efficient serving of static files through Django is being looked at currently as part of Google SOC project. For WSGI this will use wsgi.file_wrapper extensions for WSGI if available, as it is for mod_wsgi, and req.sendfile() if using mod_python. It will also support returning of headers such as 'Location', 'X-Accel-Redirect' and others, which different web hosting mechanisms and proxy front ends accept as a means of serving up static files where location is defined by a backend web application, which isn't as effecient as front end for serving static files.
通过 Django 更有效地提供静态文件目前正在被视为 Google SOC 项目的一部分。对于 WSGI,这将使用 wsgi.file_wrapper 扩展(如果可用),就像 mod_wsgi 一样,如果使用 mod_python,则使用 req.sendfile()。它还支持返回标头,例如“位置”、“X-Accel-重定向”等,不同的 Web 托管机制和代理前端接受这些标头作为提供静态文件的一种方式,其中位置由后端 Web 应用程序定义,在提供静态文件方面不如前端有效。
I am not sure if there is a project page for this in Django wiki somewhere or not, but the code changes are being committed into the branches/soc2009/http-wsgi-improvements branch of Django source code repository.
我不确定在 Django wiki 的某个地方是否有一个项目页面,但是代码更改正在提交到 Django 源代码存储库的分支/soc2009/http-wsgi-improvements 分支中。
You needn't strictly wait for that stuff. It is just putting a clean and portable interface in place across the different mechanisms. If using nginx as front end in front of Apache/mod_wsgi, you could use X-Accel-Redirect now. If using Apache/mod_wsgi 3.0 and daemon mode, you could use Location now, but do need to ensure you set up Apache correct. Alternatively, you could implement your own WSGI middleware wrapper around the Django application which looks for some response header of your own to indicate file to be returned and which uses wsgi.file_wrapper to return that instead of actual response returned from Django.
你不必严格等待那些东西。它只是在不同的机制之间放置一个干净且可移植的界面。如果在 Apache/mod_wsgi 前面使用 nginx 作为前端,您现在可以使用 X-Accel-Redirect。如果使用 Apache/mod_wsgi 3.0 和守护进程模式,您现在可以使用 Location,但需要确保您正确设置 Apache。或者,您可以在 Django 应用程序周围实现您自己的 WSGI 中间件包装器,它会查找您自己的一些响应标头以指示要返回的文件,并使用 wsgi.file_wrapper 来返回该文件而不是从 Django 返回的实际响应。
BTW, the authentication hook mechanisms listed for both mod_python and mod_wsgi by others would use HTTP basic authentication, which isn't what you wanted. This is presuming you want files to be protected by Django form based login mechanism using cookies and backend sessions.
顺便说一句,其他人为 mod_python 和 mod_wsgi 列出的身份验证挂钩机制将使用 HTTP 基本身份验证,这不是您想要的。这是假设您希望文件使用 cookie 和后端会话由基于 Django 表单的登录机制保护。
回答by Andre Miller
If I understand your question correctly you want to restrict access to files that are not being served by Django, for example, with an Apache server?
如果我正确理解您的问题,您想限制对 Django 未提供的文件的访问,例如,使用 Apache 服务器?
What you would then require is some way for this Apache server to use Django as an authentication source.
然后,您需要某种方式让这个 Apache 服务器使用 Django 作为身份验证源。
This django snippetdescribes such a method. It creates an access handler in Django which is used by Apache when a request for a static file comes in that needs to be protected:
这个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>
Hope this helps, the snippet was posted a while ago, so things might have changed between Django versions :)
希望这会有所帮助,该代码段是前一段时间发布的,因此 Django 版本之间的情况可能会有所不同:)

