我希望网站上的用户能够下载路径被遮蔽的文件,这样他们就不能直接下载。
例如,我希望URL是这样的:http://example.com/download/?f=somefile.txt
在服务器上,我知道所有可下载的文件都位于/home/user/files/文件夹中。
有没有一种方法可以让Django为下载提供这个文件,而不是试图找到一个URL和视图来显示它?
我希望网站上的用户能够下载路径被遮蔽的文件,这样他们就不能直接下载。
例如,我希望URL是这样的:http://example.com/download/?f=somefile.txt
在服务器上,我知道所有可下载的文件都位于/home/user/files/文件夹中。
有没有一种方法可以让Django为下载提供这个文件,而不是试图找到一个URL和视图来显示它?
当前回答
Django建议您使用另一台服务器来提供静态媒体(在同一台机器上运行另一台服务器是可以的)。他们建议使用lighttp这样的服务器。
设置起来非常简单。然而。如果'somefile.txt'是在请求时生成的(内容是动态的),那么你可能想让django来服务它。
Django Docs -静态文件
其他回答
你应该在生产环境中使用apache或nginx等流行服务器提供的sendfile api。多年来,我一直在使用这些服务器的sendfile api来保护文件。然后创建了一个简单的基于中间件的django应用程序,适用于开发和生产目的。您可以在这里访问源代码。
更新:在新版本的python提供者使用django FileResponse,如果可用,还增加了对许多服务器实现的支持,从lighthttp, caddy到hiawatha
使用
pip install django-fileprovider
将fileprovider app添加到INSTALLED_APPS设置中 添加fileprovider.middleware.FileProviderMiddleware到MIDDLEWARE_CLASSES设置中 在生产环境中将FILEPROVIDER_NAME设置为nginx或apache,开发时默认为python。
在基于类或函数的视图中,将响应头X-File值设置为文件的绝对路径。例如:
def hello(request):
# code to check or protect the file from unauthorized access
response = HttpResponse()
response['X-File'] = '/absolute/path/to/file'
return response
django文件提供程序以一种你的代码只需要最小修改的方式实现。
Nginx配置
要保护文件不被直接访问,可以将配置设置为
location /files/ {
internal;
root /home/sideffect0/secret_files/;
}
这里nginx在内部设置了一个url /files/只能访问的位置,如果你使用上述配置,你可以将X-File设置为:
response['X-File'] = '/files/filename.extension'
通过在nginx配置中这样做,文件将受到保护&你也可以从django视图中控制文件
对于一个非常简单但不是有效或可扩展的解决方案,你可以使用内置的django serve视图。这对于快速原型或一次性工作是非常好的,但正如在这个问题中所提到的,你应该在生产中使用apache或nginx之类的东西。
from django.views.static import serve
filepath = '/some/path/to/local/file.txt'
return serve(request, os.path.basename(filepath), os.path.dirname(filepath))
为了“两全皆美”,你可以将s.l ot的解决方案与xsendfile模块结合起来:django生成文件的路径(或文件本身),但实际的文件服务由Apache/Lighttpd处理。一旦你设置了mod_xsendfile,集成你的视图需要几行代码:
from django.utils.encoding import smart_str
response = HttpResponse(mimetype='application/force-download') # mimetype is replaced by content_type for django 1.7
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
response['X-Sendfile'] = smart_str(path_to_file)
# It's usually a good idea to set the 'Content-Length' header too.
# You can also set any other required headers: Cache-Control, etc.
return response
当然,这只有在你能控制你的服务器,或者你的主机公司已经设置了mod_xsendfile的情况下才会起作用。
编辑:
在django 1.7中,Mimetype被content_type取代
response = HttpResponse(content_type='application/force-download')
编辑: 对于nginx检查,它使用X-Accel-Redirect而不是apache的X-Sendfile头。
使用https://github.com/johnsensible/django-sendfile: https://gist.github.com/iutinvg/9907731提供对静态html文件夹的受保护访问
试一试:https://pypi.python.org/pypi/django-sendfile/
“一旦Django检查了权限,抽象的卸载文件上传到web服务器(例如Apache的mod_xsendfile)。”