2013-04-12 52 views
6

使用django-rest-framework。在nginx後面的生產環境中運行時出現HTTP 403錯誤。當我打電話的特定視圖,從APIView繼承支持GET操作,我得到:django rest框架在nginx後面給出403但不是直接使用

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

但是......我只得到這個在瀏覽器中。當我使用curl來訪問相同的URL時,我不明白。無論是直接點擊網址還是通過AJAX加載網址,Chrome和Firefox都會出現此錯誤。

如果我先通過管理員帳戶通過Django Admin登錄,則不會收到錯誤消息。

此外,我只得到這是我從後面nginx運行。如果我使用Django dev服務器或gunicorn運行,並直接點擊端口,那麼我很好,並且可以高興地匿名訪問URL。如果我把nginx放在這個前面,轉發到相同的gunicorn/runserver,我得到這個錯誤。

也許這與我的nginx proxy_pass設置有關?

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

我正在運行django rest framework 2.2.6,Django 1.5和nginx 1.2.7。

我在rest框架中設置了一個愚蠢的高數字,並查看了默認情況下似乎打開的所有權限(但也設置爲如此明確)。

任何人都可以指向正確的方向嗎?

謝謝!

魯多。

+0

django-rest-framework的認證設置是什麼? – iMom0

+0

我只是使用默認設置,看起來合適。 – Ludo

回答

0

如果您啓用了限制,您將獲得403 FORBIDDEN。基於這個問題:https://github.com/tomchristie/django-rest-framework/issues/667,關閉request.user/request.auth的懶惰評估可能是最好的做法。

+1

更新到最新版本的REST框架應該可以解決此問題。 (參考機票現已關閉) –

+0

嗨。謝謝!我在2.2.6上,看起來它包含了這個修復。我試圖按照線程,但不能看到一個簡單的方法來禁用節流。我確實設定了非常高的油門值。也許我應該嘗試一個自定義auth類?除非我另有所聞,否則我會在下一步嘗試。謝謝 – Ludo

+0

我關閉了限制和授權,一切開始工作。謝謝。 – Ludo

23

在我的情況下,我在Apache中配置了HTTP基本身份驗證,但在我的Django項目中沒有配置。由於請求具有身份驗證標頭,因此Django應用程序認爲我想用它進行身份驗證。使用這些設置在Django的REST框架我禁用認證:

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

謝謝!這完全是我的問題 – jarv

+0

你不需要禁用所有的auth類,只能刪除基本的auth。在這裏看到另一個答案http://stackoverflow.com/questions/19693433/django-rest-framework-behind-http-basic-authentication – chhantyal

+0

優秀。這是我使用VPS + Apache + Passenger(Dreamhost)的問題。 – oooyaya

3

如果這是一個基本的HTTP認證(如在@ Sjoerd的情況下),你不需要Django的認證,還可以去除Authorization頭在你的nginx的反向代理配置:

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

非常感謝!我們遇到了同樣的問題,這有幫助! –

+0

這應該是被接受的答案。 – Lev

2

當您發送到網站,這是基本的身份驗證, 客戶端(瀏覽器)發送「授權」頭之後(因爲它應該提出一個請求 - 請參見:「基本訪問認證」維基百科)。

Ngnix將它傳遞給您的應用程序。

Django Rest Framework還支持:BasicAuthentication,並且默認啓用。

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

來源:http://www.django-rest-framework.org/api-guide/authentication/

所以Django的REST的架構看到 '授權' 標頭,並認爲這是應該與密碼Django的用戶。

如果這樣的用戶不存在,那麼你得到:「HTTP 401 Unauthorized」。 見:http://www.django-rest-framework.org/api-guide/authentication/#basicauthentication

Soultions

選擇一個: 一)添加到您的網站ngnix配置

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

所以DRF不會得到 '授權' 頭,所以它不會嘗試與django用戶匹配。

此更改後 - 基本身份驗證不能在Django上側(!空頭

二)被用來擺脫(在你的Django設置)從REST_FRAMEWORK「rest_framework.authentication.BasicAuthentication」的。

如果沒有定義,添加到您的Django設置:

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

Probbably最佳解決方案。

c)使用您的django用戶/密碼進行基本身份驗證?

Realy? - 別!