简体   繁体   English

在django中测试POST端点时如何包含csrf令牌?

[英]how do you include a csrf token when testing a POST endpoint in django?

I am learning how to make an api endpoint and I am trying to write a test to see if a post request returns a 200 status code. 我正在学习如何创建api端点,我正在尝试编写一个测试,以查看post请求是否返回200状态代码。 I plan on writing more tests to see if the endpoint is returning all the expected results as well. 我计划编写更多测试,以查看端点是否也返回了所有预期的结果。 I keep getting a 403 status code and I think it is because I need to include a csrf token in the post data. 我一直收到403状态代码,我认为这是因为我需要在post数据中包含一个csrf标记。 What is a good way to test a POST endpoint in django? 在django中测试POST端点的好方法是什么?

my Test: 我的测试:

from django.test import TestCase
from app import settings
import requests

class ProjectEndpoint(TestCase):
   def post_endpoint(self):
      data = {'hello':'23'}
      post_project = requests.post(settings.BASE_URL+'/api/project', params=data)
      self.assertEqual(post_endpoint.status_code, 200)

This test keeps failing with 403 != 200 这个测试在403!= 200时仍然失败

I think it is because the view is protected against csrf attacks, but I am really not sure. 我认为这是因为视图可以防止csrf攻击,但我真的不确定。 Appreciate any insight that someone has. 欣赏某人的任何洞察力。

Actually, django doesn't enforce (by default) csrf checking with tests, as per https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#testing : 实际上,根据https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#testing,django不会强制(默认情况下)使用测试进行csrf检查:

The CsrfViewMiddleware will usually be a big hindrance to testing view functions, due to the need for the CSRF token which must be sent with every POST request. 由于需要必须与每个POST请求一起发送的CSRF令牌,CsrfViewMiddleware通常会成为测试视图函数的一大障碍。 For this reason, Django's HTTP client for tests has been modified to set a flag on requests which relaxes the middleware and the csrf_protect decorator so that they no longer rejects requests. 出于这个原因,Django的测试HTTP客户端已被修改为在请求上设置一个标志,放松中间件和csrf_protect装饰器,以便它们不再拒绝请求。 In every other respect (eg sending cookies etc.), they behave the same. 在其他方面(例如发送cookie等),它们的行为相同。

If, for some reason, you want the test client to perform CSRF checks, you can create an instance of the test client that enforces CSRF checks: 如果由于某种原因,您希望测试客户端执行CSRF检查,则可以创建执行CSRF检查的测试客户端实例:

from django.test import Client 来自django.test import客户端

csrf_client = Client(enforce_csrf_checks=True) csrf_client =客户端(enforce_csrf_checks = True)

However, this does require you to be using the Django Client vs requests; 但是,这确实需要您使用Django Client vs请求; as far as I know, Django doesn't mock/instrument/etc. 据我所知,Django没有模拟/乐器等。 requests... so you're actually hitting the real server when you run that unit test. 请求...所以当你运行单元测试时,你实际上是在击中真正的服务器。

Also note that you should name your test functions something that starts with test_ 另请注意,您应该将测试函数命名为以test_开头的内容

So something like this (when run through django manage.py test .ProjectEndpoint) 所以这样的事情(当通过django manage.py test .ProjectEndpoint运行时)

def test_post_endpoint(self):
   data = {'hello':'23'}
   c = Client() #above, from django.test import TestCase,Client
   #optional, but may be necessary for your configuration: c.login("username","password")
   response = c.post('/api/project',params=data)
   self.assertEqual(response.status_code, 200)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM