Certains fichiers sont réservés à des personnes ayant payé, avec un compte, ou encore protégés par un mot de passe. Problème: django gère l’authentification mais ne doit pas gérer l’upload car c’est le taff du serveur en front end.
Etape 1: configurer Nginx
Je suppose ici que vous avez une config Django classique avec Nginx qui fait un proxy passe vers un serveur WSGI type cherrypy, gunircorn, uwsgi, etc.
Dans votre fichier de config Nginx, rajoutez ceci:
server { ... location /secure_upload/{ internal; alias /chemin/absolu/vers/dossier/du/projet/media; } }
La directive internal
s’assure qu’une requête extérieur ne peut pas demander d’accéder à cette adresse.
Etape 2: authentifier et rediriger avec une vue Django
Dans cet exemple, on sert uniquement le fichier aux utilisateurs authentifiés. Mais on pourrait très bien le faire sur la saisie d’un code unique, vérifier les droits d’accès, etc. J’ai juste choisi le cas le plus simple.
from django.contrib.auth.decorators import login_required from django.http import HttpResponse from django.views import static from django.conf import settings @login_required() # on accepte uniquement les requête authentifiées def serve_secure_static(request, path): # en mode debug, on demande à Django de servir le fichier histoire de pas # être forcé de setuper nginx sur sa machine de dev if settings.DEBUG: return static.serve(request, path, settings.SECURE_MEDIA_ROOT) # Sinon on retourne une réponse VIDE avec en header le chemin de l'url # de l'upload interne # Nginx va l'intercepter, réaliser qu'il faut qu'il upload ce qu'il y # a à cette URL et faire le reste du boulot response = HttpResponse() response['X-Accel-Redirect'] = '/secure_upload/%s' % path return response |
Etape 3 : configurer Django
Evidément il vous faut dans le settings.py:
MEDIA_ROOT = "/chemin/absolu/vers/dossier/du/projet/media" SECURE_MEDIA_ROOT = os.path.join(MEDIA_ROOT, 'secure') |
Les dossiers doivent être créés à la mano.
Et dans urls.py:
url(r'^download/(?P .*)$', server_secure_static) |
J’allais vous demander pourquoi ne pas utiliser X-SendFile quand j’ai vu que c’était l’équivalent sous Nginx (ie http://wiki.nginx.org/XSendfile)
Donc pour les gens sous apache/lighttpd/cherokee il faut écrire:
response[‘X-Accel-Redirect’] = ‘full/path/vers/le/fichier/secure’
et le chemin en question n’a pas besoin d’être dans la configuration du serveur (à vérifier).
En tout cas je prends note pour quand j’aurais enfin le temps de passer à Nginx.
Une petite erreur s’est glissée dans le morceau de config du serveur Nginx:
Il faut inverser
/chemin/absolu/vers/dossier/du/projet/media
et/secure_upload/