CSRF
CSRF
django为用户实现防止跨站请求伪造的功能,通过中间django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
全局:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部:
-
csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
-
csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
开启csrf后 , 当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错.
通过form提交
在form表单里面需要添加{%csrf_token%}
这样当你查看页面源码的时候,可以看到form中有一个input是隐藏的
当用户访问login页面的时候,会生成一个csrf的随机字符串,,并且cookie中也存放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功
cookie中存放的csrftoken如下图
csrf装饰器
from django.views.decorators.csrf import csrf_exempt,csrf_protect,ensure_csrf_cookie
csrf_exempt #某个视图不需要进行csrf校验上
csrf_protect #某个视图需要进行csrf校验
ensure_csrf_cookie #确保生成csrf的cookie
csrf_exempt
csrf_exempt,不能加在类上,也不能加在方法上,只能加在dispatch上
作用:中间件开启csrf校验,针对POST等可通过这个装饰器豁免,不在进行校验
方法一:
class Login(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
ret = super().dispatch(request, *args, **kwargs)
return ret
方法二:
@method_decorator(csrf_exempt,name='dispatch')
class Login(View):
def get(self, request, *args, **kwargs):
pass
def post(self, request, *args, **kwargs):
pass
csrf_protect
当中间件django.middleware.csrf.CsrfViewMiddleware禁用后,可通过csrf_protect开启,可以加在方法上
ensure_csrf_cookie
生成csrftoken的cookie
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs):
return render(request, 'login.html')
csrf校验流程
1.csrf中间件中执行process_request:
1. 从cookie中获取到csrftoken的值
2. csrftoken的值放入到 request.META
2.执行process_view
-
查询视图函数是否使用csrf_exempt装饰器,使用了就不进行csrf的校验
-
判断请求方式:
-
如果是GET', 'HEAD', 'OPTIONS', 'TRACE'
不进行csrf校验
-
其他的请求方式(post,put)
进行csrf校验:
1.获取cookie中csrftoken的值
2.获取csrfmiddlewaretoken的值
能获取到 ——》 request_csrf_token
获取不到 ——》 获取请求头中X-csrftoken的值 ——》request_csrf_token
比较上述request_csrf_token和cookie中csrftoken的值,比较成功接收请求,比较不成功拒绝请求。
-