Login

nginx x-accel-redirect protection of static files

Author:
sean
Posted:
November 29, 2007
Language:
Python
Version:
.96
Score:
3 (after 3 ratings)

This snippet requires nginx as your front end server (for serving static files) and any django enabled server as a backend that only gets the dynamic requests (I use apache with mod_python). If you have no idea what I'm talking about, you probably won't need this snippet. I previously tried something similar just using mod_python, but this was too unstable for my needs (the PythonAuthenHandler seems to be called multiple times for no apparent reason). The patch from that snippet was also used as a base for this ticket.

This is part of an authentication mechanism I use for protecting static files. Nginx has the so called x-accel-redirect feature, that tells nginx to serve an internal (read 'protected') file if the backend response has the ['X-Accel-Redirect'] header set. No other headers are touched, but by deleting all relevant headers in the default django response, nginx will create those headers for us.

The usage is pretty simple:

  • set up nginx as a proxy for apache + mod_python + django (google for this if you don't know how)

  • configure nginx as shown in the code snippet (for testing leave out the internal part to see if the files are accessible)

  • configure your urls.py to point to the validation view

  • make your sites hrefs point to the view instead of the file directly (those real urls will be completely hidden from your visitors)

  • Done!
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# in your nginx.conf put something like this
'''
location /protected {
                internal; # only the apache instance can access this url directly
                alias   /protected/files/path/;
        }
'''

# put something like this in your views.py and give it an entry in the urls.py

# no point in letting unauthenticated users into the view
# but this depends on your requirements
@login_required
def nginx_accel(request,id):
    '''
    default django view, where id is an argument that identifies
    the ressource to be protected
    '''
    allowed = False
    pFile = get_object_or_404(ProtectedFile,pk=id)

    # do your permission things here, and set allowed to True if applicable
    if allowed:
        response = HttpResponse()
        url = '/protected/protected.file' # this will obviously be different for every ressource
        # let nginx determine the correct content type 
        response['Content-Type']=""
        response['X-Accel-Redirect'] = url
        return response
    
    return HttpResponseForbidden()

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 5 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.