2013-04-12 4 views
6

Korzystanie z django-rest-framework. Otrzymuję błędy HTTP 403 podczas uruchamiania w produkcji za Nginx. Kiedy zadzwonić konkretny pogląd, który dziedziczy APIView wspierać operację GET, otrzymuję:Django reszta ramy daje 403, gdy za nginx, ale nie bezpośrednio

{"detail": "Invalid username/password"} 

Ale ... ja tylko dostać to w przeglądarce. Nie rozumiem, kiedy używam curl dla tego samego adresu URL. Dostaję ten błąd, niezależnie od tego, czy kliknę URL bezpośrednio, czy załaduję adres URL za pośrednictwem AJAX, zarówno w przeglądarce Chrome, jak i Firefox.

Nie otrzymam błędu, jeśli najpierw zaloguję się przez administratora Django z kontem administratora.

Ponadto, mam tylko to, że uruchamiam zza nginx. Jeśli uruchomię serwer Django lub gunicorn i trafiam bezpośrednio w port, nic mi nie będzie i z przyjemnością trafię anonimowo w adres URL. Jeśli następnie ustawię nginx przed tym, aby przekazać ten sam gunicorn/runserver, otrzymam ten błąd.

Może to ma coś wspólnego z ustawieniami mojego proxy nginx?

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; 
} 

Używam django rest framework 2.2.6, Django 1.5 i nginx 1.2.7.

Ustawiam dławienie na głupią, wysoką liczbę w ramach reszty i przyjrzałem się uprawnieniom, które domyślnie były domyślnie otwarte (ale tak samo jawnie ustawione).

Czy ktoś może wskazać mi właściwy kierunek?

Dzięki!

Ludo.

+0

jakie są twoje ustawienia uwierzytelniania dla Django-Rest-Framework? – iMom0

+0

Używam tylko wartości domyślnych, które wyglądały na odpowiednie. – Ludo

Odpowiedz

0

Otrzymasz 403 ZABRONIONE, jeśli masz włączone ograniczanie przepustnicy. Na podstawie tego problemu: https://github.com/tomchristie/django-rest-framework/issues/667, wyłączenie leniwej oceny request.user/request.auth jest prawdopodobnie najlepszą rzeczą do zrobienia.

+1

Aktualizacja tego rozwiązania do najnowszej wersji REST powinna rozwiązać ten problem. (Bilet referencyjny jest teraz zamknięty) –

+0

Witam. Dzięki! Mam jednak wersję 2.2.6, która wygląda na to, że zawiera tę poprawkę. Próbuję śledzić wątek, ale nie widzę łatwego sposobu na wyłączenie dławienia. Ustawiłem bardzo wysoką wartość przepustnicy. Może powinienem spróbować niestandardowej klasy auth? Spróbuję tego następnym razem, chyba że usłyszę inaczej. Dzięki – Ludo

+0

Wyłączyłem dławienie i auth i wszystko zaczęło działać. Dzięki. – Ludo

23

W moim przypadku miałem podstawowe uwierzytelnianie HTTP skonfigurowane w Apache, ale nie w moim projekcie Django. Ponieważ żądanie zawierało nagłówki uwierzytelniania, aplikacja Django uznała, że ​​chcę się z nim uwierzytelnić. I wyłączona uwierzytelniania w ramach Django REST za pomocą tych ustawień:

REST_FRAMEWORK = { 
    'DEFAULT_AUTHENTICATION_CLASSES': [] 
} 
+1

Dziękujemy! to był mój problem dokładnie – jarv

+0

Nie musisz wyłączać wszystkich klas auth, tylko usuń podstawowe uwierzytelnianie. Zobacz kolejną odpowiedź tutaj http://stackoverflow.com/questions/19693433/django-rest-framework-behind-http-basic-authentication – chhantyal

+0

Doskonały. To był mój problem przy użyciu VPS + Apache + Passenger (Dreamhost). – oooyaya

3

Jeśli jest to podstawowy auth HTTP (podobnie jak w przypadku @ sjoerd) i nie trzeba się uwierzytelnianie django, można również usunąć Authorization nagłówek w swojej nginx odwrotnej konfiguracji proxy:

location/{ 
    ... 
    proxy_set_header Authorization ""; 
} 
+1

Dzięki za to! Właśnie natknęliśmy się na ten sam problem, to pomogło! –

+0

To powinna być zaakceptowana odpowiedź. – Lev

2

Podczas wysyłania żądania do strony, która jest za podstawowego uwierzytelniania klienta (przeglądarki) wysyła nagłówek „pozwolenie” (tak jak powinno - patrz: „uwierzytelnianie dostępu Podstawowe” na wikipedia).

Ngnix przekazuje go do Twojej aplikacji.

Django Rest Framework obsługuje również: BasicAuthentication i jest domyślnie włączona.

REST_FRAMEWORK = { 
    'DEFAULT_AUTHENTICATION_CLASSES': (
     'rest_framework.authentication.BasicAuthentication', 
     'rest_framework.authentication.SessionAuthentication', 
    ) 
} 

źródło: http://www.django-rest-framework.org/api-guide/authentication/

Więc django-rest-framework widzi nagłówek 'pozwolenie', i uważa, że ​​to powinno być Django użytkownika z hasłem.

Jeśli taki użytkownik nie istnieje, otrzymasz komunikat: "HTTP 401 Unauthorized". Patrz: http://www.django-rest-framework.org/api-guide/authentication/#basicauthentication

Soultions

Wybierz jeden: a) dodaj do ngnix stronie config

location/{ 
    ... 
    proxy_set_header Authorization ""; 
    ... 
} 

tak DRF nie dostanie nagłówek 'pozwolenie', więc nie będzie próbował aby dopasować użytkownika django.

Po tej zmianie - podstawowe auth nie może być używany na stronie django (pusty nagłówka

B!) Pozbyć się "rest_framework.authentication.BasicAuthentication" z REST_FRAMEWORK (w ustawieniach django).

Jeśli nie zdefiniowano, dodać do swoich ustawień django:

REST_FRAMEWORK = { 
    'DEFAULT_AUTHENTICATION_CLASSES': (
     'rest_framework.authentication.SessionAuthentication', 
    ) 
} 

Probbably najlepsze rozwiązanie.

c) Użyj swojego użytkownika/hasła django do podstawowego uwierzytelnienia?

Naprawdę? - Nie rób tego!