Django 和 Nginx X-accel-redirect

Django and Nginx X-accel-redirect

到目前为止,我一直在摸索着保护 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

}

我的Url文件

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 错误。这里有什么明显的错误吗?谢谢!

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

感谢@Paulo Almeida,这解决了这个问题。

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

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

我的 url 是...

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)

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

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

urls.py:

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

views.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() 得到 deprecated in Django 3.1 所以只需使用 re_path() 代替
  • nginx 配置中的别名而不是 root:我不想让“/protectedMedia/”出现在 url 中(它没有用),另见 nginx docs
  • 2021 年 6 月 14 日编辑:德语变音符号(äüö 等)在媒体路径中不起作用,因此我编辑了上面的答案以包含 quote from urllib.parse

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