To manage user access to static files in a Django application when serving the files with Nginx, you can implement a secure system to control access. Here’s a step-by-step approach to solve this problem:
- Protect the Static Files with Nginx
First, configure Nginx to restrict direct access to the static files. This can be done by using internal redirects and access control in Nginx.
Edit your Nginx configuration file (e.g., /etc/nginx/sites-available/your_site):
nginx
server {
listen 80;
server_name your_domain.com;
location /static/ {
internal;
alias /path/to/staticfiles/;
}
location /media/ {
internal;
alias /path/to/mediafiles/;
}
location /protected_static/ {
alias /path/to/staticfiles/;
add_header X-Accel-Redirect /static/;
}
location /protected_media/ {
alias /path/to/mediafiles/;
add_header X-Accel-Redirect /media/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
In this configuration:
/static/ and /media/ locations are marked as internal, meaning they cannot be accessed directly from the outside.
The /protected_static/ and /protected_media/ locations act as a proxy to these internal locations, adding an X-Accel-Redirect header to perform an internal redirect.
- Secure URLs with Django
In Django, create a view that checks user permissions before serving the static files. This view will generate URLs that Nginx can handle.
from django.http import HttpResponse, Http404
from django.conf import settings
import os
def serve_protected_file(request, file_path):
# Check user permissions here
if not request.user.is_authenticated:
raise Http404
# Generate the X-Accel-Redirect header
response = HttpResponse()
response['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(file_path)
response['X-Accel-Redirect'] = os.path.join('/protected_static/', file_path)
response['Content-Type'] = ''
return response
- Update URLs
Update your urls.py to point to the new view:
from django.urls import path
from . import views
urlpatterns = [
path('protected_static/<path:file_path>/', views.serve_protected_file, name='serve_protected_file'),
]
- Use the Secure URLs in Templates
In your templates, use the secure URLs:
<a href="{% url 'serve_protected_file' file_path='path/to/your/file.jpg' %}">Download</a>
Additional Security Measures
Token-based access: For added security, generate temporary access tokens that expire after a certain period.
Logging and monitoring: Log access to protected files and monitor for unusual activity.
Following these steps ensures that static files are protected and only accessible to authorized users. The combination of Nginx's internal redirects and Django's permission checks allows you to manage user access to URLs securely.