本篇介绍csrf相关的装饰器,中间件,以及对部分源码进行分析。
csrf相关的装饰器
| 1 | from django.views.decorators.csrf import csrf_exempt,csrf_protect | 
csrf_exempt
- 豁免csrf校验
FBV
| 1 | # home.html | 
- 只要添加 csrf_exempt这个装饰器就可以豁免csrf校验
| 1 | from django.views.decorators.csrf import csrf_exempt | 
CBV
关于 csrf_exempt 两种无效的使用:
- 不用 method_decorator 是会报错的
| 1 | from django.views.decorators.csrf import csrf_exempt | 
- 使用method_decorator 直接加在方法上也不行
| 1 | from django.views.decorators.csrf import csrf_exempt | 
关于给视图函数添加装饰器,详见 Django的View
正确的姿势:
- 给dispatch方法添加csrf_exempt装饰器
| 1 | 
 | 
csrf_protect
- 强制进行csrf校验
FBV
- 先在settings中注释掉关于csrf的中间件
| 1 | from django.views.decorators.csrf import csrf_protect | 
CBV
- 不用method_decorator 是不行的。
| 1 | class Home2(View): | 
ensure_csrf_cookie
待补充
csrf中间件
有两个token
- 一个是Cookie中的csrftoken

- 一个是 input标签,名字为 csrfmiddlewaretoken,value是64位

cookie中的csrf token是不变的, input标签内的token是变化的。
想要通过csrf校验的先提条件,必须有csrftoken的cookie
- 1 - 设置{% csrf %} - 后面的源码分析中也会解释,有了它,就会在response的Cookie中设置csrftoken 
- ensure_csrf_cookie 这个装饰器,有了它,会在每次请求的response的Cookie中设置csrftoken 
然后会把这两个token值作比较
- 从cookie中获取csrftoken的值与post请求提交的数据中的csrfmiddlewaretoken的值做对比。
- 如果request.POST中获取不到csrfmiddlewaretoken这个值,会尝试从请求头中获取 x-csrftoken的值,并且拿这个值与csrftoken做对比,对比成功也能通过校验。
源码分析
- 设置csrf_exempt = True , 会在 CsrfViewMiddleware的process_view中使用
| 1 | # django\views\decorators\csrf.py | 
- CsrfViewMiddleware中间件的定义
| 1 | # django\middleware\csrf.py | 

