2011-09-04 18 views
25

Zrobiłem kilka badań dotyczących pobierania plików z kontrolą dostępu, używając Django. Moim celem jest całkowite zablokowanie dostępu do pliku, z wyjątkiem dostępu do niego przez określonego użytkownika. Czytałem, że przy korzystaniu z Django, X-Sendfile jest jedną z metod z wyboru do osiągnięcia tego (na podstawie innych pytań SO, itp.). Moje rozumienie szczątkowe używając X-Sendfile z Django jest:Django - Zrozumienie X-Sendfile

  1. Użytkownik żąda URI, aby uzyskać plik chroniony
  2. Django app decyduje, który plik, aby powrócić na podstawie adresu URL, a uprawnienie kontroli użytkownika, itp
  3. Aplikacja Django zwraca odpowiedź HTTP z zestawem nagłówkowym "X-Sendfile" do ścieżki pliku serwera
  4. Serwer internetowy znajduje plik i zwraca go do requestera (zakładam, że serwer WWW usuwa także "X-Sendfile" nagłówek po drodze)

W porównaniu z ładowaniem pliku bezpośrednio z Django, X-Sendfile wydaje się być bardziej skuteczną metodą uzyskiwania zabezpieczonych plików do pobrania (ponieważ mogę polegać na Nginx do udostępniania plików, w porównaniu z Django), ale pozostawia mi 2 pytania:

  1. Czy moje wyjaśnienie X-Sendfile jest co najmniej abstrakcyjnie poprawne?
  2. Czy to naprawdę bezpieczne, zakładając, że nie zapewniam normalnego dostępu HTTP na poziomie front-end (np. http://www.example.com/downloads/secret-file.jpg) do katalogu, w którym plik jest przechowywany (tj. Nie przechowuj go w katalogu public_html)? A może doświadczony technologicznie użytkownik może badać nagłówki itp. I tworzyć inżynierię wsteczną w celu uzyskania dostępu do pliku (aby następnie rozpowszechniać)?
  3. Czy to naprawdę duża różnica w wydajności. Czy mam zamiar podkręcić mój serwer aplikacji, dostarczając 8b porcjowanych plików 150Mb bezpośrednio z Django, czy jest to rodzaj problemu? Powodem, dla którego pytam, jest to, że jeśli obie wersje są prawie równe, wersja Django byłaby lepsza z powodu mojej zdolności do robienia rzeczy w Pythonie, takich jak rejestracja liczby zakończonych pobrań, pasma pobierania itd.

Dzięki z góry.

+0

W krokach, które opisałem powyżej, jedno nie jest dla mnie jasne: kiedy powiedziałeś "Aplikacja Django zwraca odpowiedź HTTP z zestawem nagłówków X-Sendfile", kto jest odbiorcą tej odpowiedzi? Domyślam się, że będzie to serwer WWW (np. Nginx). Jeśli tak, to kto inicjował żądanie, które jest obsługiwane przez aplikację Django? – MLister

+0

@MLister - użytkownik (przeglądarka internetowa) - w zasadzie chciałbyś ustawić widok taki jak 'get_file (request, file_name)' (coś podobnego do tego) i kiedy użytkownik odwiedza URL, zwróć odpowiedź z '' X-Sendfile' wskazuje poprawną lokalizację podanego pliku (po dodaniu dowolnej logiki w widoku, aby określić, czy użytkownik powinien mieć możliwość pobrania pliku).Nginx przechwyci odpowiedź w drodze i zwróci odpowiedź z plikiem (do pobrania). – orokusaki

+0

, więc 'nginx' musi być ustawiony * przed * serwerem aplikacji' Django'? W przeciwnym razie, w jaki sposób 'nginx' może przechwycić odpowiedź w drodze na zewnątrz? – MLister

Odpowiedz

19
  1. Tak, właśnie tak działa.
  2. Dokładna implementacja zależy od serwera WWW, ale w przypadku nginx zaleca się oznaczenie lokalizacji jako wewnętrznej, aby uniemożliwić dostęp z zewnątrz.
  3. Nginx może asynchronicznie wyświetlać pliki, podczas gdy z Django potrzebujesz jednego wątku na żądanie, co może sprawiać problemy w przypadku większej liczby równoległych żądań.

Pamiętaj, aby wysłać nagłówek X-Accel-Przekierowanie dla nginx zamiast X-Sendfile. Aby uzyskać więcej informacji, patrz http://wiki.nginx.org/XSendfile.