拥有 POST'able API 和 Django 的 CSRF 中间件

Posted

技术标签:

【中文标题】拥有 POST\'able API 和 Django 的 CSRF 中间件【英文标题】:Having a POST'able API and Django's CSRF Middleware拥有 POST'able API 和 Django 的 CSRF 中间件 【发布时间】:2011-01-25 05:01:48 【问题描述】:

我有一个 Django webapp,它有一个前端、Web 可访问的组件和一个可由桌面客户端访问的 API。但是,现在有了新的 CSRF 中间件组件,来自桌面客户端的经过 POST 的 API 请求会得到 403。

我明白为什么会发生这种情况,但是在不影响安全性的情况下解决此问题的正确方法是什么?有没有什么方法可以在 HTTP 标头中表明这是一个 API 请求,Django 不应该检查 CSRF 或者这是一个糟糕的策略?

编辑--

我目前使用的方法是桌面客户端设置一个header,X-Requested-With: XMLHttpRequest。这有点 hacky,但我不确定如何更好地处理。

【问题讨论】:

由于您的临时解决方案(来自上次编辑)基本上是关闭 csrf,您可以完全关闭中间件,不是吗? :) 网站的其余部分(前端部分)需要启用它 【参考方案1】:

为您的桌面客户端拆分一个视图并用csrf_exempt 装饰它们怎么样?

【讨论】:

这正是设置,但csrf_exempt 似乎没有什么不同。它仍然给那个装饰器一个 403。 +1,因为根据文档,这应该可以工作,即使它不是。 这仅在无法通过浏览器访问 API 时有效。否则这可能会非常危险,因为随后可能会针对 API 从另一个站点伪造请求。【参考方案2】:

如果您使用的是基于类的视图,那么您将需要 csrf_exempt 调度方法,而不是像这样的 post 方法:

@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
    return super(MyView, self).dispatch(request, *args, **kwargs)

查看此错误单: https://code.djangoproject.com/ticket/15794

【讨论】:

【参考方案3】:

从 Django 1.1 开始,CSRF 代码将自动允许 AJAX 请求通过,因为浏览器似乎进行了适当的安全检查。这是original commit 和documentation。

【讨论】:

嗯,这不是真的,是吗?在您提供的链接中,它确实说您需要添加一个额外的标头才能使 AJAX 工作,而不是它会自动工作。

以上是关于拥有 POST'able API 和 Django 的 CSRF 中间件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 的一个序列化程序中拥有两个模型

完整的Django+vuejs构建音乐网站项目

在 Python 3 上的 Django 中使用 Google 站点验证 API

Django中的RESTful api在Django中使用inbult视图,无需创建2个url

Django Rest 框架的基于密钥的访问

模型中带有 json 字段的 Django crud api