Django and Nginx X-accel-redirect

This is what fixed this issue thanks to @Paulo Almeida.

In the nginx file I changed what I previosly had too...

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

My url is...

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

And the View is...

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)

This works perfectly! Now only admin users can access the media files stored in my media folder.


This helped me a lot, just a small update and modification:

urls.py:

re_path(r'^media/', protectedMedia, name="protect_media")

views.py:

from django.http import HttpResponse
from django.contrib.admin.views.decorators import staff_member_required


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

I had to change the nginx config to the following:

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

Notes:

  • I prefer using the decorator, as it automatically redirects to the login page (when specified in settings) and sets the "next" page.
  • url() gets deprecated in Django 3.1 so just use re_path() instead
  • alias instead of root in nginx config: I don't want to have "/protectedMedia/" appear in the url (and it didn't work), see also nginx docs

If you're still stuck somewhere, this gave me further backround information: https://wellfire.co/learn/nginx-django-x-accel-redirects/