AberSheeran
Aber Sheeran

Django CSRF保护问题

起笔自
所属文集: 程序杂记
共计 1242 个字符
落笔于

Django自带的CSRF保护是一个是十分棒的插件。在使用Django开发的过程中,它仅仅只需要你引入一行代码,就可以保护你的表单不受CSRF攻击的困扰。

但在开发Api时,它会困扰着许多程序员,接下来我们分两个情况来解决它(都是基于你在使用 Cookies 进行身份验证的时候,不是用 Cookies 也就没有 CSRF 防护的需要了,直接删掉 Django 中对应的中间件即可)。

同源请求

对于同源网站而言,这十分好解决。在Django里有两个设置,分别是

  • CSRF_COOKIE_NAME,用于指定Cookies中存放CSRF token值的名称,默认是csrftoken;

  • CSRF_HEADER_NAME,用于指定从请求头中读取CSRF token的头部名称,默认是HTTP_X_CSRFTOKEN,翻译到实际的头名称应该是——X-CSRFTOKEN。

你只需要使用JS读取Cookies当中的CSRF token,在发送请求时附带对应的头部信息即可。如果你使用的是axios之类的较为完善的库,你甚至都不需要手动读Cookies,只需要增加对应的options即可。以axios为例:

const ap = axios.create({
    xsrfHeaderName: 'X-CSRFToken',
    xsrfCookieName: 'csrftoken',
})

当然,也可以通过修改 Django 的配置来适应 axios 的默认值,axios 的默认值如下所示。

// `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
xsrfCookieName: 'XSRF-TOKEN', // default

// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default

跨域请求

对于跨域请求,需要绕过HTTP Referer报头的限制,我们配置起来也很容易。例如我需要upload.abersheeran.com能够跨域请求到api.abersheeran.com,只需要在api的项目配置里增加

CSRF_TRUSTED_ORIGINS = [
    'upload.abersheeran.com',
]

如果是想允许abersheeran.com下所有子域名都被允许,那么可以配置为

CSRF_TRUSTED_ORIGINS = [
    '.abersheeran.com',
]

然后再使用同源请求的方法进行访问即可。

如果你觉得本文值得,不妨赏杯茶
Coding-WebHook
uwsgi日志分割