使用 Django Rest Framework 测试 CSRF 验证

2024-01-15

我正在使用 Django Rest Framework 3,想测试 CSRF 验证。

首先,我初始化 DRFAPIClient:

client = APIClient(enforce_csrf_checks=True)

然后我为用户设置密码,以便我可以登录并获取会话:

superuser.set_password('1234')
superuser.save()
client.login(email=superuser.email, password='1234')

现在我们需要一个 CSRF 令牌。为此,我只需创建一个请求并从 cookie 中检索令牌。

response = client.request()
csrftoken = client.cookies['csrftoken'].value

检查代码时,这似乎有效,我得到了一个看起来有效的 CSRF 令牌。然后我执行 POST 请求,传入csrfmiddlewartoken范围:

data = {'name': 'My fancy test report', 'csrfmiddlewaretoken': csrftoken}
response = client.post(API_BASE + '/reports', data=data, format='json')
assert response.status_code == status.HTTP_201_CREATED, response.content

问题是,这失败了:

tests/api/test_api.py:156: in test_csrf_success
    assert response.status_code == status.HTTP_201_CREATED, response.content
E   AssertionError: {"detail":"CSRF Failed: CSRF token missing or incorrect."}
E   assert 403 == 201
E    +  where 403 = <rest_framework.response.Response object at 0x7f7bd6453bd0>.status_code
E    +  and   201 = status.HTTP_201_CREATED

使用 DRF 测试 CSRF 验证的正确方法是什么?


EDIT

因此,经过一番研究后,我发现了以下内容:

Django 不一定会在标头中设置 CSRF 令牌,除非它正在渲染显式具有以下内容的模板:csrf_token包括模板标签。这意味着您需要请求一个使用 csrf 令牌呈现表单的页面,或者您需要创建一个用以下修饰的令牌请求视图ensure_csrf_cookie.

由于 csrf 令牌在每个会话中都是唯一的,因此可以创建如下所示的通用令牌设置视图:

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def token_security(request):
    return HttpResponse()  # json or whatever

然后,任何时候您希望 POST 到 CSRF 保护的端点并且 cookie 中没有 CSRF 令牌,请针对此视图发出 GET,它应该设置 cookie,然后可以将其用于 POST。

原答案如下:


以下内容在我的测试中有效(我使用工厂来创建 User 对象,但您可以手动创建它们):

class TestLoginApi(APITestCase):
    def setUp(self):
        self.client = APIClient(enforce_csrf_checks=True)
        self.path = reverse("registration:login")
        self.user = UserFactory()

    def tearDown(self):
        self.client.logout()

    def _get_token(self, url, data):
        resp = self.client.get(url)
        data['csrfmiddlewaretoken'] = resp.cookies['csrftoken'].value
        return data

   def test_login(self):
        data = {'username': self.user.username,
                'password': PASSWORD}
        data = self._get_token(self.path, data)

        # This should log us in.
        # The client should re-use its cookies, but if we're using the
        # `requests` library or something, we'd have to re-use cookies manually.
        resp = self.client.post(self.path, data=data)
        self.assertEqual(resp.status_code, 200)
        etc.

如果这一切都是动态完成的,您还必须确保您的视图在 GET 上设置了 cookie,因为根据 Django 文档(请参阅警告) https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax,如果您不从具有以下内容的模板发回,则不会自动设置{% csrf_token %} set.

如果您需要设置它,看起来像这样(在您的 DRF views.py 中):

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie

    @method_decorator(ensure_csrf_cookie)
    def get(self, request, *args, **kwargs):
        return SomeJson...

最后,对于我的 Django Rest Framework 视图,我必须确保 POST 也受到 csrf 保护(但这看起来不像您遇到的问题):

from django.views.decorators.csrf import csrf_protect

    @method_decorator(csrf_protect)
    def post(self, request, *args, **kwargs):
        return SomeJson...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Django Rest Framework 测试 CSRF 验证 的相关文章

随机推荐

  • 从另一个类访问静态变量

    我在同一个包中有两个类 我已经宣布了static variable在一个类中 并且想要在另一个类中访问该变量 这是我的代码 其中声明了静态变量 public class wampusGUI extends javax swing JFram
  • 重复使用黄瓜步骤

    我想重复使用一些黄瓜步骤 但似乎找不到正确的方法 我想写一个这样的步骤 Given I login with credentials type do stuff with type being one of invalid or valid
  • 了解自下而上的杆切割实施

    In 算法导论 CLRS https rads stackoverflow com amzn click com 0262033844 科门等人 下面谈谈解决切棒问题 第369页 EXTENDED BOTTOM UP CUT ROD p n
  • 如何用计算表达式替换捕获组(向捕获组添加整数值)

    我需要用这种格式转换一些字符串 B12F34 类似的事情 12号楼 34楼 但我必须向第二个捕获组添加一个值 例如 10 这样新字符串将如下所示 12号楼 楼44 我可以使用这个 postgres 句子来完成几乎所有事情 但我不知道如何将值
  • 如何抑制 Flash 迁移警告 (1090)

    在 Flash Professional CS4 中 当我使用鼠标 键盘输入处理程序名称 例如 onMouseDown onKeyUp 等 时 我会收到 迁移问题 警告 即使我已为它们添加了事件侦听器 这些名称对于函数来说是完全合法的 但由
  • 让 Ninject 管理我的交易状态,实践关注点

    我让 Ninject 管理我的ISession and ITransaction使用以下注册方法在 Fluent nHibnerate 中进行状态 我想知道它是否足以控制事务 或者我是否需要将其放在其他地方 想法是 每个ISession根据
  • 哎呀!失去与未定义的连接 - 连接建立后立即失去连接

    过去几天我一直在尝试 spring 4 websocket 但有一个问题 我正在使用 apache tomcat 8 这不是一个 Maven 项目 这是我的片段 索引 jsp
  • css - 如何拉伸和自动调整背景图像大小

    我试图让我的背景图像延伸到整个页面 但到目前为止我有这个 这是我想要在浏览器窗口中拉伸的图片 我的外部 CSS 包含以下代码 hr color sienna p margin left 20px body background image
  • 从另一个线程关闭表单

    我有这个运行的代码 exe string openEXE C Users marek Documents Visual Studio 2012 Projects tours tours bin Debug netpokl exe Proce
  • 如何扩展 MongoDB?

    我知道 MongoDB 可以垂直扩展 如果我的磁盘空间不足怎么办 我目前正在使用 EC2 和 EBS 如您所知 我必须为 EBS 分配固定大小 如果 MongoDB 的增长大于 EBS 的大小怎么办 我是否必须创建更大的 EBS 并复制并粘
  • AsyncTask 中的 ProgressDialog

    我试图在从 HTTP 服务器加载 RSS 提要时显示自定义进度对话框 我进行了艰苦的搜索 但没有任何帮助我做到这一点 我唯一知道的是该解决方案应该使用AsyncTask 但我对传递给它的参数感到困惑AsyncTask 这是我的活动 publ
  • Python中四分位距应该如何计算?

    我有一个数字列表 1 2 3 4 5 6 7 我想要一个函数来返回这个数字列表的四分位数范围 四分位数间距是上四分位数和下四分位数之间的差值 我尝试使用 NumPy 函数和 Wolfram Alpha 计算四分位数范围 我发现所有的答案 从
  • 错误:R Shiny 图的第一个参数无效

    我编写了一个 R 脚本来使用 R 来训练自己和其他人使用 Shiny 人们可以选择一个数据集并在基础图上绘制 x 和 y 变量 还有一些其他用户定义的参数 这一切都有效 但它也会引发 错误 第一个参数无效 这可以在 绘图 选项卡 在闪亮的仪
  • Python:计算 Pandas 中两列之间的 tf-idf 余弦相似度时出现 MemoryError

    我正在尝试计算 Pandas 数据框中两列之间的 tf idf 向量余弦相似度 一列包含搜索查询 另一列包含产品标题 余弦相似度值旨在成为搜索引擎 排名机器学习算法的 特征 我在 iPython 笔记本中执行此操作 不幸的是遇到了 Memo
  • 在 javascript 中替换多个
    替换为单个

    我想更换多个 br 带有单个的标签 br 在一段文字中 我的文字就像 p fhgfhgfhgfh p br br p ghgfhfgh p br br p fghfghfgh p br br p fghfghfgh p br br p fg
  • Haskell 有什么大惊小怪的? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • XPath:通过当前节点属性选择当前和下一个节点的文本

    如果这是一个重复的问题 我很抱歉 但我在 SO 或其他地方找不到另一个问题来处理我需要的内容 这是我的问题 我在用着scrapy从中获取一些信息this http www utm utoronto ca regcal WEBLISTCOUR
  • 程序下载 - IE CHROME - “不常下载,可能很危险。”

    我有一个 C 程序的安装程序 我将其上传到我的网站 但每当我尝试在 chrome 或 IE 中下载它时 我都会收到 MY FILE 不常下载 可能很危险 只有单击小箭头并从菜单中选择 保留 才能保留它 只有十分之一的用户能够获取我的程序 我
  • AWS Api Gateway 使用消息属性连接到 SQS

    我已按照本教程连接了一个 Api 网关方法来推送到 SQS 队列 https dzone com articles creating aws service proxy for amazon sqs https dzone com arti
  • 使用 Django Rest Framework 测试 CSRF 验证

    我正在使用 Django Rest Framework 3 想测试 CSRF 验证 首先 我初始化 DRFAPIClient client APIClient enforce csrf checks True 然后我为用户设置密码 以便我可