Django 的 CSRF 是什么原理?

作者站长头像
站长
· 阅读数 6

好像是浏览器发出一个 request 的时候,会在 request header 的 cookie 中携带一个 token,然后在 request 的 body 中也携带一个 token。

然后 Django server 提取 request header cookie 中的 token 和 request body 中的 token?然后比较这两个 Token 是否相同?这个相同是指字符串字面量是否相同吗?还是有什么计算规则?

问题是,跨站攻击的时候,把这两个 token 填成一样不就行了?这能防住啥?


对于跨站攻击,cookie 中的 token 和 form 中的 token 都拿不到吗?都拿不到的话,为什么还需要两个 token?


浏览器本身就不允许跨域,为什么 Django 还要搞一个 csrf?

回复
1个回答
avatar
test
2024-07-08

通过浏览器的 F12 调试发现

与 csrf 相关的 token 一共有两个:

  • csrfmiddlewaretoken,这个 token 存在于 request 的 body 中
  • csrftoken,这个 token 存在于 request 的 cookie 中

先详细看看 csrftoken

answer image

当我们的浏览器第一次访问的这个网站的时候,request 中当然是没有 csrftoken 的。然后 server 给我们一个 response,这个 response 的 header 中有 Set-Cookie,就如下面的截图一样

第二、三、四、五 etc 次访问的时候,request header cookie 中都会带上这个 csrftoken,对应的 response header 中也有 Set-Cookie 这个 csrftoken。

这个 csrftoken 只要不发生『登录』、『登出』等操作,这个 csrftoken 就不会变,意思就是你 不停刷新,不停请求,都是这个 csrftoken,所以 csrftoken 具有不可变性

再来看看 csrfmiddlewaretoken

先明确一点,必须是先有 GET,才能 POST

当然需要 POST 之前,必然是先 GET 获取这个界面

当你 GET 的时候,Django server 会把 csrfmiddlewaretoken 放在 html 中发给你的浏览器

answer image

然后当你 POST 的时候,浏览器会把之前 GET 的 csrfmiddlewaretoken 带上,一起 POST 给 Django server

answer image

而这个 csrfmiddlewaretoken 是变化的,你每次 GET 获得的 csrfmiddlewaretoken 都是不一样的

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容