8

到目前为止,我一直在尝试保护 Django 的媒体文件,但没有成功!我只是想让它只有管理员用户可以访问媒体文件夹。这是我的 Nginx 文件。

server {
    listen 80;
    server_name xxxxxxxxxx;

    location = /favicon.ico {access_log off; log_not_found off;}
    location /static/ {
          alias /home/{site-name}/static_cdn/;
   }
   location /media/ {
          internal;
          root /home/{site-name}/;
   }

   location / {
this is setup and working. Didn't include Code though

}

我的网址文件

urlpatterns = [
    url(r'^media/', views.protectedMedia, name="protect_media"),
] 

而我的看法

def protectedMedia(request):

    if request.user.is_staff:
        response = HttpResponse()
        response['Content-Type'] = ''
        response['X-Accel-Redirect'] = request.path
        return response

    else:
        return HttpResponse(status=400)

这会产生 404 Not Found Nginx 错误。这里有什么明显的错误吗?谢谢!

顺便说一句,我尝试将 /media/ 添加到 Nginx 设置中根 URL 的末尾。

4

2 回答 2

17

感谢@Paulo Almeida,这就是解决此问题的原因。

在 nginx 文件中,我也更改了我以前拥有的内容......

   location /protectedMedia/ {
          internal;
          root /home/{site-name}/;
   }

我的网址是...

url(r'^media/', views.protectedMedia, name="protect_media"),

视图是...

def protectedMedia(request):

    if request.user.is_staff:
        response = HttpResponse(status=200)
        response['Content-Type'] = ''
        response['X-Accel-Redirect'] = '/protectedMedia/' + request.path
        return response

    else:
        return HttpResponse(status=400)

这完美!现在只有管理员用户可以访问存储在我的媒体文件夹中的媒体文件。

于 2017-08-25T02:02:34.980 回答
7

这对我帮助很大,只是一个小的更新和修改:

网址.py:

re_path(r'^media/(?P<path>.*)', protectedMedia, name="protect_media")

视图.py:

from urllib.parse import quote
from django.http import HttpResponse
from django.contrib.admin.views.decorators import staff_member_required


@staff_member_required
def protectedMedia(request, path):
    response = HttpResponse(status=200)
    response["Content-Type"] = ''
    response['X-Accel-Redirect'] = '/protectedMedia/' + quote(path)
    return response

我不得不将 nginx 配置更改为以下内容:

location /protectedMedia/ {
      internal;
      alias /home/{site-name}/;
}

笔记:

  • 我更喜欢使用装饰器,因为它会自动重定向到登录页面(在设置中指定时)并设置“下一个”页面。
  • url()在 Django 3.1 中被弃用,所以只需使用re_path()代替
  • 别名而不是 nginx 配置中的 root:我不想让“/protectedMedia/”出现在 url 中(它不起作用),另请参阅nginx 文档
  • 从 2021 年 6 月 14 日开始编辑:德语变音符号(äüö 等)在媒体路径中不起作用,所以我编辑了上面的答案以包含来自 urllib.parse 的引用

如果你仍然被困在某个地方,这给了我更多的背景信息:https ://wellfire.co/learn/nginx-django-x-accel-redirects/

于 2020-07-08T08:31:58.143 回答