16

我正在开发一个 Django Web 应用程序,该应用程序(除其他外)需要处理使用POST请求发送的事务状态信息。

除了支付网关支持的 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)

但是,我怎样才能伪造成功的提交?我试过设置HTTP_REFERER例如extra,但这不起作用;该视图显然仍然看到一个空白标题。 self.client.post(..., extra={'HTTP_REFERER': 'http://foo/bar'})

测试客户端是否甚至支持自定义标头?如果没有,是否有解决方法?我正在使用 Django 1.1,如果可能的话,我宁愿不升级。

4

2 回答 2

28

几乎是对的。其实是:

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

在阅读;** _ _ _ 最终成为函数本身的额外关键字参数的字典。test/client.pyextra

于 2012-08-05T19:31:25.217 回答
5

您可以将 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'))

这样您就不需要在每次发出请求时都传递标头。

于 2018-02-03T22:27:13.137 回答