Django中间件之csrf_token

我的未来我决定 提交于 2020-11-29 03:59:41

一 、CSRF中间件 :CSRF跨站请求伪造

如果就简单些一个登录表格的页面,提交这个属于跨站提交,这时候要通过中间件的CSRF的验证。

1.先了解下两个装饰器

  from django.views.decorators.csrf import csrf_exempt, csrf_protect
  csrf_exempt    给单个视图排除校验
  csrf_protect    给单个视图必须校验

2.简单写一下示例:

settings.py文件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',  # 此时是注释
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

urls.py文件

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'login',views.login)
]

views.py文件

from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt, csrf_protect

# @csrf_protect # 必须校验csrf_token
# @csrf_exempt # 排除校验csrf_token
def login(request):
return render(request, 'login.html')
 

html文件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
  {% csrf_token %}
    <p>
        用户名:<input type="text" name="user">
    </p>
    <p>
        密码:<input type="password" name="pwd">
    </p>
    <button type="submit">登录</button>
</form>
</body>
</html>

 

现在 settings 设置的相当于全局的设置,而   @csrf_exempt或者@csrf_protect这两个装饰器是对局部的设置

  如果使用csrf_protect,那么html中提交的表单没有csrf_token 就会报错

二 、查看Django源码

1.process_request方法中:
  从请求的cookie中获取csrftoken的值 ——》csrf_token ——》request.META['CSRF_COOKIE']


2.process_view方法中:
  1. 如果视图函数加上了csrf_exempt的装饰器        不做校验
  2. 如果请求方式是'GET', 'HEAD', 'OPTIONS', 'TRACE'   也不做校验  
  3. 其他的请求方式做校验
    request.META.get('CSRF_COOKIE') —— 》 csrf_token   # 拿到csrf_token   

    request_csrf_token = ""    # 取值有两种方法
     1.
    request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')  # 从request.POST中获取csrfmiddlewaretoken对应的值
     2.
    request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')  # 从请求头中获取X-csrftoken 的值 

    request_csrf_token 和 csrf_token 进行对比校验
      如果校验成功 正常走
      如果校验不成功 拒绝

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!