我使用 nginx,这通常是我的解决方案。也许类似的东西可用于 Apache。不知道。
在 nginx 中,代理可以返回带有标头的响应,X-Accel-Redirect
其中包含 nginx 应该重定向的位置。例如,使用以下 nginx 配置:
server {
...
location / {
proxy_pass: ...;
}
location /media/secure/ {
internal;
alias ...;
}
}
如果代理通行证将返回:
X-Accel-Redirect: /media/secure/somefile;
然后 nginx 会将请求从代理重定向到该/media/secure/
位置,从而提供静态文件。
所以我通常在 Django 中对用户进行身份验证,然后将带有位置的标头返回到 nginx 服务的文件中。这很好,因为 Django 不必提供静态文件,用户不能只访问该安全位置(因为该internal
指令),还因为如果所有 mime 类型都在 nginx 中配置,那么所有文件都可以正确提供。 .
同样,这是针对 nginx,而不是针对 Apache,但也许 Apache 也有类似的东西。
编辑
这是一个简单的 Django 代码片段,假设您使用与上面相同的 nginx 设置。如果在 GET 中提供了路径,则此视图提供安全文件:
@login_required()
def serve_secure_static(request, file_root=os.path.join(settings.MEDIA_ROOT, 'secure')):
if not request.method == 'GET':
return HttpResponseBadRequest('Only GET allowed')
if not 'file' in request.GET:
return HttpResponseBadRequest('File query must be provided')
# make sire loggen user is allowed to see the file
# maybe check some custom permission
file_path = request.GET['file']
# if in DEBUG, make Django serve static file
# because nginx might not be configured
if settings.DEBUG:
abs_file_path = os.path.join(file_root, file_path)
file_data = open(abs_file_path, 'rb').read()
return HttpResponse(file_data, mimetype=mimetypes.guess_type(file_path))
# else make nginx serve static file
else:
redirect_url = '/%s' % file_path
response = HttpResponse()
response['X-Accel-Redirect'] = redirect_url
return response
因此,如果您将此视图添加到 urlconfig:
url(r'^serve_secure_static/$', 'server_secure_static')
您可以通过以下方式请求安全文件:
http://domain.com/serve_secure_static/?file=path/to/file/here/relative/to/media/secure.css
这将从
/media/secure/path/to/file/here/relative/to/media/secure.css