1.客户(模板页面(html页面) ) --------> 服务员(函数处理业务请求) --------> 厨子 (使用原材料做饭:数据库相关的操作)
2.模板页面(views)---->控制器(controller:函数)---->模型 (models:建表与数据库相关)
1.django独有:M(model:用类建表)、T(tempalte:HTML模板) 、V(views:业务逻辑函数)
M(model) : models
T(tempalte) :  views
V(views): controller
1.三种安全攻击:CSRF, xss, sql注入 2.csrf:跨站请求伪造攻击
3.相关内容:(参考:https://www.cnblogs.com/mengbin0546/p/9966431.html)
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能又分为全局和局部。
?
全局:
?
中间件 django.middleware.csrf.CsrfViewMiddleware
?
局部:
?
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
?
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
?
注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect
4.当用==post==提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错,这也是之前我们一直将其注释的原因
# 1.开启全局的csrf验证:
    # 1.1 settings中,打开注释
        ‘django.middleware.csrf.CsrfViewMiddleware‘,
    # 1.2 表单中,开启csrf_token
        # html文件中:
            <form>
                {% csrf_token %}  # 写了会通过验证
                <input type=‘text‘>
            </form>
        # 在views文件中:
            def test1(request):
                return HttpResponse("ok")
    # 1.3 如上,全站都会进行csrf验证
        
# 2.局部的函数, 不进行csrf验证
    # 2.1 settings中,打开注释 
        ‘django.middleware.csrf.CsrfViewMiddleware‘,
    # 2.2 在views中:
        from django.views.decorators.csrf import csrf_exempt
        
5.当用户通过get方式访问页面的时候,会生成一个csrf的随机字符串,并且cookie中也存放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功
6.CBV(class base views): 就是在视图里使用类处理请求
1.提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
2.可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator
from django.views import View
    
7.通过 ajax 验证CSRF
如果通过ajax进行提交数据,这里提交的csrftoken是通过请求头中存放,需要提交一个字典类型的数据,即这个时候需要一个key(X_CSRFtoken)
在views中的login函数中:from django.conf import settings,然后打印print(settings.CSRF_HEADER_NAME),这里需要注意一个问题,这里导入的settings并不是我们在项目文件下看到的settings.py文件,这里是是一个全局的settings配置,而当我们在项目目录下的settings.py中配置的时候,我们添加的配置则会覆盖全局settings中的配置
print(settings.CSRF_HEADER_NAME)打印的内容为:HTTP_X_CSRFTOKEN。这里的HTTP_X_CSRFTOKEN是django在X_CSRF的前面添加了HTTP_,所以实际传递的是就是X_CSRFtoken,而在前端页面的ajax传递的时候由于不能使用下划线所以传递的是X_CSRFtoken
<body>
<form action="/test/" method="post">
    {% csrf_token %}
    <input type="text">
    <input type="submit" value="sub">
</form>
</body>
?
<!-- 将token放置到请求头中,携带过去  -->
<script>
//在页面中会有一个隐藏的input标签中,存放csrf验证码,我们可以通过伪类进行获取
token = $(‘input[name="csrfmiddlewaretoken"]‘).val()
?
// headers : {‘X-CSRFToken‘: token} 
?
$.ajax({
    type:‘POST‘, 
    url:‘/test/‘,
    data:{‘name‘:‘xxxx‘},
    headers : {‘X-CSRFToken‘: token},
    sucess;fucntion(data){
    console.log(data);
    }
})
</script>
8.总结:
1.CSRF在ajax提交的时候是通过请求头传给后台的
2.csrf在前端的key为:X-CSRFtoken,到后端的时候django会自动添加HTTP_。因此最后为:HTTP_X_CSRFtoken
原文:https://www.cnblogs.com/zrx19960128/p/11444904.html