用 django 有多久,跟 csrf 这个概念打交道就有久。

  • 每次初始化一个项目时都能看到 django.middleware.csrf.CsrfViewMiddleware 这个中间件
  • 每次在模板里写 form 时都知道要加一个 {% csrf_token %} tag
  • 每次发 ajax POST 请求,都需要加一个 X_CSRFTOKEN 的 header

什么是 CSRF

CSRF, Cross Site Request Forgery, 跨站点伪造请求。举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果

某个用户已经登录到你的网站上了,那么当这个用户点击这个恶意网站上的那个链接时,就会向你的网站发来一个请求,

你的网站会以为这个请求是用户自己发来的,其实呢,这个请求是那个恶意网站伪造的。

Django 提供的 CSRF 防护机制

django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,

这样就能避免被 CSRF 攻击。

  1. 在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token
  2. 在所有的 POST 表单时,必须包含一个 csrfmiddlewaretoken 字段 (只需要在模板里加一个 tag, django 就会自动帮你生成,见下面)
  3. 在处理 POST 请求之前,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否一样。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden.
  4. 在所有 ajax POST 请求里,添加一个 X-CSRFTOKEN header,其值为 cookie 里的 csrftoken 的值

Django 里如何使用 CSRF 防护

  • 首先,最基本的原则是:GET 请求不要用有副作用。也就是说任何处理 GET 请求的代码对资源的访问都一定要是“只读“的。
  • 要启用 django.middleware.csrf.CsrfViewMiddleware 这个中间件。
  • 再次,在所有的 POST 表单元素时,需要加上一个 {% csrf_token %} tag。
  • 在渲染模块时,使用 render。render会处理 csrf_token 这个 tag,  从而自动为表单添加一个名为 csrfmiddlewaretoken 的 input。
【注】csrf 装饰器
全局:

  中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

from django.views.decorators.csrf import csrf_exempt,csrf_protect
  • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
  • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
 
代码:
settings.py

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""
Django settings for my19django project.
Generated by 'django-admin startproject' using Django 1.10.3.
For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '=_!qf8#b(*b-bd0texdrf9og219b1guo=uepdsll6v(6(n#4*w'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
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',
]
ROOT_URLCONF = 'my19django.urls'
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
WSGI_APPLICATION = 'my19django.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

  

urls.py

?
1
2
3
4
5
6
7
8
from django.conf.urls import url
from django.contrib import admin
from myapp01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^csrf/', views.csrf),
]

views.py
?
1
2
3
from django.shortcuts import render
def csrf(req):
    return render(req, 'csrf.html')

csrf.html
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/csrf/" method="post">
        {% csrf_token %}
        <input type="text" name="v"/>
        <input type="submit" name="提交"/>
    </form>
    <input type="button" value="Ajax提交" onclick="DoAjax();"/>
    <script src="/static/jquery-2.1.4.min.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>
         // 去cookie中获取值
        var csrftoken = $.cookie('csrftoken');
        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });
        function DoAjax(){
            $.ajax({
                url: '/csrf/',
                type: 'POST',
                data: {'k1': 'v1'},
                success: function (data) {
                    console.log(data);
                }
            })
        }
    </script>
</body>
</html>

转载于:https://www.cnblogs.com/xiaoyaojinzhazhadehangcheng/p/8042437.html

循序渐进PYTHON3(十三) --4-- DJANGO之CSRF使用相关推荐

  1. Django web : CSRF verification failed. Request aborted.

    错误标题:CSRF verification failed. Request aborted. 错误描述: HelpReason given for failure:CSRF cookie not s ...

  2. 第九章 Django框架——csrf请求伪造和csrf_token使用

    第九章 Django框架--csrf请求伪造和csrf_token使用 一.csrf请求伪造 二.csrf_token使用 三.简单的csrf_token应用 四.Ajax使用csrf_token 一 ...

  3. Django与CSRF 、AJAX

    CSRF(Cross-site request forgery)跨站请求伪造,是一种常见的网络攻击手段,具体内容和含义请大家自行百度. Django为我们提供了防范CSRF攻击的机制. 一.基本使用 ...

  4. django防止csrf跨域伪造攻击

    Csrf跨域伪造攻击:使用当前浏览器还在生效状态的cookie对指定网站进行操作.最初针对的是银行网站的转账. Django本身会对csrf进行校验,在django的1.4版本之前,csrf默认关闭, ...

  5. django 中 csrf问题 的解决方法

    2019独角兽企业重金招聘Python工程师标准>>> crsf 解决几个关键方法, 1 模板文件 ,使用form的  添加  {%csrf_token%} 2 setting 文件 ...

  6. django出现 CSRF cookie not set

    解决方案: 问题:页面访问时报错 Forbidden (CSRF cookie not set.): xxx 解决方法: 修改settings.py文件,注释掉 django.middleware.c ...

  7. Django项目--csrf攻击

    1.案例流程图: 2.django防止csrf的方式: 1 ) Django中默认打开csrf中间件.settings.py文件中: MIDDLEWARE_CLASSES = ('django.con ...

  8. django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块

    CBV加装饰器 第一种 @method_decorator(装饰器) 加在get上 第二种 @method_decorator(login_auth,name='get') 加在类上 第三种 @met ...

  9. Django POST CSRF verification failed. Request abor

    问题 在使用Django搭建好测试环境后,写了一个提交POST表单提交留言的测试页面. 如图: 填写表单,点击"提交留言"按钮提交到服务器,却出现 Forbidden (403) ...

最新文章

  1. Centos修改系统语言
  2. 如何在使用babel和webpack时生成源图?
  3. 天天用Synchronized,底层原理是个啥?
  4. oracle开审计记录变动的表,Oracle未开启审计情况下追踪表变更记录
  5. 通过enum实现枚举类
  6. 史上最全的stm32资料库4---常见问题及编译工具篇
  7. asp.net + ajax + sqlserver 自动补全功能,asp.net+ajax+sqlserver自动补全功能实现解析
  8. asp微信会员卡管理系统,超小的源码_带asp微信支付源码
  9. XML NameSpace
  10. SDOI2019R1游记
  11. 游戏 mysql优化工具_MySQL 性能优化神器 Explain 使用分析
  12. ST集成传感器方案实现电子罗盘功能
  13. WPS桌面右键新建菜单缺少新建文档入口
  14. ApacheCN 翻译活动进度公告 2019.5.31
  15. 微信渠道带参数二维码应用场景怎么添加?
  16. sqldblink建好不能查询_眉山这个停车场显示有车位却不能停?原来是……
  17. LiveNVR安防摄像头Web无插件直播平台页面的快速集成方法
  18. 如何购买服务器及域名(阿里)
  19. Linux alsa-lib c语言 播放wav音频
  20. networkx教程

热门文章

  1. 区块链是大数据生态圈技术之一_区块链技术再发力,携手智能制造构建产业生态圈...
  2. centos7删除文件命令_干货 | 玩转云文件存储——利用CFS实现web应用的共享访问...
  3. 数据库的事务,隔离级别和3大范式
  4. c++三维静态数组的定义与作为函数的传递
  5. 注册COM组件cmd(管理员权限)
  6. 架构重构改善既有代码的设计
  7. PMP读书笔记(第8章)
  8. laydate根据开始时间或者结束时间限制范围
  9. JavaScript 所有数据类型
  10. @ResponseBody ResponseEntity