Dateien auf dem Webserver mit Django nur bestimmten Usern zugänglich machen

Falc410

Vice Admiral
Registriert
Juni 2006
Beiträge
6.419
Ich frage mich gerade, wie das funktioniert, dass nur eingeloggte Nutzer z.B. Dateien herunterladen dürfen - und zwar ohne PHP oder Plugins.

Hintergrund ist: Wir hosten eine Webseite mit Django (Python), die über WSGI mit einem Apache Server kommuniziert. Statische Files, z.B. MP3 / MP4 liegen im wwwroot und werden vom Apache ausgeliefert. Ich kann zwar in Django / Python abfragen ob User X berechtigt ist, aber im Prinzip kann jeder User mit dem direkten Link auf die Dateien zugreifen. Ich kann also nicht verhindern, dass User X den Link teilt und sich jemand anderes dann die Dateien herunterlädt. Der Apache kennt ja keine User.

Hatte schon überlegt ob ich den Link hinter Javascript verstecke, aber die Dateien sollen im Browser abgespielt / angezeigt werden. Wir benutzen dafür einfach das HTML5 Audio bzw. Video Tag - funktioniert gut. Aber jeder kann im Seitenquelltext dann natürlich den Link sehen - der zeigt ja auf die Datei die geladen worden ist. Nur den Download können wir nicht unterbinden.

Wie schaffen das andere Webseiten? Ich könnte natürlich ein Plugin benutzen, aber wir wollen explizit keine Plugins voraussetzen. Im Prinzip bräuchte ich eine Art Proxy der dann die eigentliche Datei lädt - aber solange diese irgendwie vom Apache ausgeliefert wird, kann man diese auch immer herunterladen. Trotzdem gibts das ja bei fast jeder Webseite, dass man selbst mit einem Link keine Berechtigung hat auf die Datei zuzugreifen wenn man nicht die richtigen Privilegien hat. Wie lösen die das?
 
In dem es nicht der Webserver direkt ausliefert, sondern die Haupt-Applikation oder ein externer Service wie S3 (mit einem authorisiertem Link), der das kann.
 
Falc410 schrieb:
aber im Prinzip kann jeder User mit dem direkten Link auf die Dateien zugreifen. Ich kann also nicht verhindern, dass User X den Link teilt und sich jemand anderes dann die Dateien herunterlädt. Der Apache kennt ja keine User.
Kann man ihm aber beibringen... wobei es besser ist den direkten Download für alle im Apache zu sperren und das dann über Python abzuwickeln. Dann hat man nur eine Userverwaltung.
 
Django sagt halt explizit in der Doku, dass man keine Static Files damit serven soll - das soll der Webserver machen. Wahrscheinlich aus Performancegründen.

@zoz Das hatte ich auch schon mal gefunden aber noch nicht eingesetzt weil ich auf anderen Seiten gelesen habe, dass xsendfile nicht mehr funktioniert mit modernen Browsern.
 
Es sind halt aber keine wirklichen static files. Die URL gibt unterschiedliche Antworten, je nachdem ob angemeldet oder nicht.
 
Jo, ist ne Performance-Sache wenn das über Python läuft. Aber anders kriegt man die Userverwaltung nicht hin (zumindest wüst ich keinen Sinnvollen Weg wie man die Apache Userverwaltung für die .htaccess mit einem Framework wie Django verbinden könnte)
 
Falc410 schrieb:
@zoz Das hatte ich auch schon mal gefunden aber noch nicht eingesetzt weil ich auf anderen Seiten gelesen habe, dass xsendfile nicht mehr funktioniert mit modernen Browsern.

Das von mir verlinkte Package hat nichts mit dem Browser zu tun, der Browser bekommt davon gar nichts mit das der Request nach der Authentifizierung wieder an Nginx übergeben wird.
 
  • Gefällt mir
Reaktionen: Falc410
zoz schrieb:
Das von mir verlinkte Package hat nichts mit dem Browser zu tun, der Browser bekommt davon gar nichts mit das der Request nach der Authentifizierung wieder an Nginx übergeben wird.


Ok ich glaube jetzt habe ich verstanden wie es funktioniert mit mod_wsgi und mod_rewrite.

Durch mod_wsgi und dem Django sendfile Plugin, erzeuge ich einen internal request auf ein File welches von Apache bereitgestellt wird. Durch mod_rewrite kann ich prüfen ob jemand von extern versucht hat auf die URL zuzugreifen und das wird dann verhindert, wenn es ein interner Request war, dann wird es durchgelassen und dann kann Apache das file serven.

Dann brauche ich auch mod_xsendfile nicht - das hatte ich nämlich mal gefunden aber ist wohl veraltet, daher wollte ich es nicht nutzen.

Danke - ich werde das mal ausprobieren. Aber so dürfte es funktionieren.
 
Zurück
Oben