【问题标题】:how to disable csrf in testing django?如何在测试 django 时禁用 csrf?
【发布时间】:2015-05-13 00:55:14
【问题描述】:

我在使用 csrf 令牌测试视图时遇到问题。

这段代码

class ViewTests(TestCase):
    def test_bets_view(self):
        login_page = self.client.get('/users/login/')
        print(login_page.content)

返回带有 CSRF 隐藏输入的 HTML。

还有这个东西,我需要和之前的 HTML 比较一下,

expected_html = render_to_response('login.html',
                                   dictionary={'form': LoginForm()})

没有隐藏的 CSRF 输入。所以断言失败。

如何在测试客户端中禁用 CSRF 渲染?

【问题讨论】:

  • 您正在执行什么样的测试?渲染的 HTML 的精确匹配?您应该测试功能/验证/导航/UI(部分,而不是整个页面)。

标签: django testing csrf


【解决方案1】:

您可以像这样在单元测试中覆盖中间件设置:

from django.test import override_settings

testing_middleware = [ ... anything but csrf middleware goes here ]


class TestWhatever(TestCase)
    @override_settings(MIDDLEWARE=testing_middleware)
    def testSomething():
        # no csrf error will occur 
        self.client.post('/', data={ ... })

【讨论】:

    【解决方案2】:

    首先,您在测试中获取页面并从中提取 csrf 令牌:

    page = self.client.get("/users/login")
    token = page.context.get("csrf_token")
    

    然后你使用相同的token来渲染模板并进行比较:

    expected_html = TemplateResponse(
        page.wsgi_request,                                              
        "login.html",                                   
        context={"form": LoginForm(), "csrf_token": token}).render()
    
    assert expected_html.content == page.content
    

    【讨论】:

      【解决方案3】:

      您永远不应该比较完整的 HTML 内容。只需检查功能。如果您需要不惜一切代价禁用csrf,我猜以下逻辑应该会有所帮助。

      在您的 views.py 文件中,添加以下包

      from django.views.decorators.csrf import csrf_exempt

      然后就在你正在执行检查的函数定义之前,添加这个 sn-p:

      @csrf_exempt

      这将禁用 csrf 的默认验证。即使您的传入请求具有隐藏的 csrf 令牌,您的服务器功能也会完全忽略它。这应该可以禁用 csrf。

      【讨论】:

      • 但这并没有禁用csrf 在测试客户端,它无处不在,不是吗?即您的测试通过并且您的应用程序不安全。到目前为止,xbello 是更好的方法 - 它告诉您如何在测试客户端上使用 csrf。
      猜你喜欢
      • 1970-01-01
      • 2016-12-02
      • 2013-05-03
      • 2013-01-22
      • 2014-09-20
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      • 2013-11-08
      相关资源
      最近更新 更多