14

我試圖使用TokenAuthentication與我的意見之一。 如http://django-rest-framework.org/api-guide/authentication.html所述,我將從登錄名中收到的令牌添加爲HTTP標頭,該標頭在我發送的請求中稱爲:「授權」。Django TokenAuthentication缺少'授權'http標頭

問題是在我的unittests認證失敗。 展望TokenAuthentication類我看到被檢查的標題是「HTTP_AUTHORIZATION」而不是「授權」

我使用的視圖:

class DeviceCreate(generics.CreateAPIView): 
    model = Device 
    serializer_class = DeviceSerializer 

    authentication_classes = (TokenAuthentication,) 
    permission_classes = (IsAuthenticated,) 

改變頭爲「HTTP_AUTHORIZATION」似乎工作,但感覺不對勁。

我錯過了什麼?

回答

16

展望TokenAuthentication類我看到被檢查的標題是「HTTP_AUTHORIZATION」而不是「授權」

並不完全正確,在請求META字典做查找時,頭,它的實際上找不到前面的HTTP_,所以request.META.get('HTTP_AUTHORIZATION', '')實際上查找請求中的Authorization標頭。

的問題是,在我的單元測試認證失敗 改變頭爲「HTTP_AUTHORIZATION」似乎工作

我沒有帶雙重檢查測試客戶端的外觀,但我相信,設置HTTP_AUTHORIZATION你需要做的是獲得相當於實際設置Authorization標題的內容。如果你真的提出了一個http請求,你應該發現設置auth頭的工作原理與你期望的完全一致。

request.META文檔瀏覽:https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

編輯

request.META查找頭Django文檔:

隨着CONTENT_LENGTH和CONTENT_TYPE的例外,因爲上面給出, 請求中的任何HTTP標頭將被轉換爲META密鑰 將所有字符轉換爲大寫,替換帶有 的任何連字符下劃線併爲該名稱添加HTTP_前綴。因此,例如,稱爲X-Bender的 標頭將被映射到META密鑰HTTP_X_BENDER。與測試客戶端設置頁眉

Django文檔:

但是,您可以使用關鍵字參數來設定一些默認的標題。例如,這將在每個請求發送User-Agent HTTP標頭:

C =客戶端(HTTP_USER_AGENT = '的Mozilla/5.0')

4

Tom's answer是好的,但不完成。

您的代碼在開發環境中可以正常工作(使用runserver),但如果您在WSGI服務器(在我的情況下爲Apache)中嘗試它,服務器可以剝離授權標頭!

您可以在Boone's Blog找到一個很好的修復了你的Apache的conf保持Authorization頭的請求,並使其發揮作用很大:

RewriteEngine on 
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] 
+0

鏈接的博客是死的,但尖救了我的理智。不知道Apache/WSGI正在剝頭文件! – twig 2018-01-14 22:18:09