2019-10-08 详解Django的CSRF认证

详解Django的CSRF认证

1.csrf原理

csrf要求发送post,put或delete请求的时候,是先以get方式发送请求,服务端响应时会分配一个随机字符串给客户端,客户端第二次发送post,put或delete请求时携带上次分配的随机字符串到服务端进行校验

2.Django中的CSRF中间件

首先,我们知道Django中间件作用于整个项目。

在一个项目中,如果想对全局所有视图函数或视图类起作用时,就可以在中间件中实现,比如想实现用户登录判断,基于用户的权限管理(RBAC)等都可以在Django中间件中来进行操作

Django内置了很多中间件,其中之一就是CSRF中间件

MIDDLEWARE_CLASSES= ['django.middleware.security.SecurityMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.auth.middleware.SessionAuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',]

上面第四个就是Django内置的CSRF中间件

3.Django中间件的执行流程

Django中间件中最多可以定义5个方法

process_request

process_response

process_view

process_exception

process_template_response

Django中间件的执行顺序

1.请求进入到Django后,会按中间件的注册顺序执行每个中间件中的process_request方法    如果所有的中间件的process_request方法都没有定义return语句,则进入路由映射,进行url匹配    否则直接执行return语句,返回响应给客户端2.依次按顺序执行中间件中的process_view方法    如果某个中间件的process_view方法没有return语句,则根据第1步中匹配到的URL执行对应的视图函数或视图类    如果某个中间件的process_view方法中定义了return语句,则后面的视图函数或视图类不会执行,程序会直接返回3.视图函数或视图类执行完成之后,会按照中间件的注册顺序逆序执行中间件中的process_response方法    如果中间件中定义了return语句,程序会正常执行,把视图函数或视图类的执行结果返回给客户端    否则程序会抛出异常4.程序在视图函数或视图类的正常执行过程中    如果出现异常,则会执行按顺序执行中间件中的process_exception方法    否则process_exception方法不会执行    如果某个中间件的process_exception方法中定义了return语句,则后面的中间件中的process_exception方法不会继续执行了5.如果视图函数或视图类中使用render方法来向客户端返回数据,则会触发中间件中的process_template_response方法

CsrfViewMiddleware中间件中定义了process_request,process_view和process_response三个方法

从Django项目配置文件夹中读取CSRF_USE_SESSIONS的值,如果获取成功,则从session中读取CSRF_SESSION_KEY的值,默认为'_csrftoken',如果没有获取到CSRF_USE_SESSIONS的值,则从发送过来的请求中获取CSRF_COOKIE_NAME的值,如果没有定义则返回None。

再来看process_view方法

在process_view方法中,先检查视图函数是否被csrf_exempt装饰器装饰,如果视图函数没有被csrf_exempt装饰器装饰,则程序继续执行,否则返回None。接着从request请求头中或者cookie中获取携带的token并进行验证,验证通过才会继续执行与URL匹配的视图函数,否则就返回403 Forbidden错误。

实际项目中,会在发送POST,PUT,DELETE,PATCH请求时,在提交的form表单中添加

{%csrf_token%}

即可,否则会出现403的错误

2019-10-08 详解Django的CSRF认证_第1张图片

5.csrf_exempt装饰器和csrf_protect装饰器

5.1 基于Django FBV

在一个项目中,如果注册起用了CsrfViewMiddleware中间件,则项目中所有的视图函数和视图类在执行过程中都要进行CSRF验证。

此时想使某个视图函数或视图类不进行CSRF验证,则可以使用csrf_exempt装饰器装饰不想进行CSRF验证的视图函数

同样的,如果在一个Django项目中,没有注册起用CsrfViewMiddleware中间件,但是想让某个视图函数进行CSRF验证,则可以使用csrf_protect装饰器

csrf_protect装饰器的用法跟csrf_exempt装饰器用法相同,都可以加上视图函数上方装饰视图函数或者在URL路由映射中直接装饰视图函数

5.1 基于Django CBV

上面的情况是基于Django FBV的,如果是基于Django CBV,则不可以直接加在视图类的视图函数中了

此时有三种方式来对Django CBV进行CSRF验证或者不进行CSRF验证

方法一,在视图类中定义dispatch方法,为dispatch方法加csrf_exempt装饰器


方法二:为视图类上方添加装饰器


方式三:在url.py中为类添加装饰器


csrf_protect装饰器的用法跟上面一样

你可能感兴趣的:(2019-10-08 详解Django的CSRF认证)