2012-08-03 32 views
9

我正在研究一個Django Web應用程序,該應用程序需要處理使用POST請求發送的交易狀態信息。在Django測試中設置HTTP_REFERER標頭

除了通過支付網關支持的HTTP的安全,我的看法檢查request.META['HTTP_REFERER']針對settings.py入口,試圖阻止不道德的事:

if request.META.get('HTTP_REFERER', '') != settings.PAYMENT_URL and not settings.DEBUG: 
    return HttpResponseForbidden('Incorrect source URL for updating payment status') 

現在,我想工作,如何進行測試這種行爲。

我可以很容易地產生一個失敗; HTTP_REFERER是(很可能)None與正常的網頁加載:

def test_transaction_status_succeeds(self): 
    response = self.client.post(reverse('transaction_status'), { ... }) 
    self.assertEqual(response.status_code, 403) 

如何,不過,我可以假一成功提交?我已經嘗試在extra,例如HTTP_REFERER中設置。self.client.post(..., extra={'HTTP_REFERER': 'http://foo/bar'}),但這是行不通的;該視圖顯然仍然看到一個空白標題。

測試客戶端是否支持自定義標頭?如果不是,有沒有解決辦法?我使用Django 1.1,如果可能的話,寧願不升級。

+0

這不是你的問題,但對於有困難的人來說:Django並沒有意識到我發送的頭文件,因爲我沒有像文檔[這裏](https:// docs)那樣正確地轉換他們的名字。 djangoproject.com/en/1.6/topics/testing/tools/#django.test.client.Client.get),如[描述CGI規範](http://tools.ietf.org/html/draft-robinson- WWW接口-00#頁-8)。例如,'X-CSRFToken'應該是'HTTP_X_CSRFTOKEN'。改變它們之後,我可以簡單地將它們用作kwargs,就像下面supervacuo的回答一樣。 – 2014-03-31 19:58:19

回答

14

幾乎正確。它實際上是:

def transaction_status_suceeds(self): 
    response = self.client.post(reverse('transaction_status'), {}, HTTP_REFERER='http://foo/bar') 

我已經錯過了**(散射運營商/關鍵字參數拆包經營者/ whatever)時reading the source of test/client.py; extra最終成爲函數本身的額外關鍵字參數的字典。

+0

當試圖使用它時,我得到了一個「__init __()」,它有一個意外的關鍵字參數'HTTP_REFERER''。也許它在更新版本的django中發生了變化? – 2015-04-14 21:21:56

+0

@StevenRogers,它聽起來像你可能已經完成了'c = Client(HTTP_REFERER ='http:// foo/bar')'(我唯一能想到的就是'__init__')。我建議把這個作爲kwarg添加到'post()'&'get()';我剛剛在Django 1.7.3上測試了它,它似乎工作正常... – supervacuo 2015-04-16 09:48:41

0

你可以通過HTTP標頭的Client構造:

from django.test import Client 
from django.urls import reverse 

client = Client(
    HTTP_USER_AGENT='Mozilla/5.0', 
    HTTP_REFERER='http://www.google.com', 
) 
response1 = client.get(reverse('foo')) 
response2 = client.get(reverse('bar')) 

這樣你就不需要每次提出請求時通過頭。