Loading

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开启,可以加在方法上

生成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

  1. 查询视图函数是否使用csrf_exempt装饰器,使用了就不进行csrf的校验

  2. 判断请求方式:

    1. 如果是GET', 'HEAD', 'OPTIONS', 'TRACE'

      不进行csrf校验

    2. 其他的请求方式(post,put)

      进行csrf校验:

      1.获取cookie中csrftoken的值

      2.获取csrfmiddlewaretoken的值

      ​ 能获取到 ——》 request_csrf_token

      ​ 获取不到 ——》 获取请求头中X-csrftoken的值 ——》request_csrf_token

      比较上述request_csrf_token和cookie中csrftoken的值,比较成功接收请求,比较不成功拒绝请求。

posted @ 2019-09-02 11:55  陌路麒麟  阅读(87)  评论(0编辑  收藏  举报