一、MVC和MTV
1.客户(模板页面(html页面) ) --------> 服务员(函数处理业务请求) --------> 厨子 (使用原材料做饭:数据库相关的操作)
2.模板页面(views)---->控制器(controller:函数)---->模型 (models:建表与数据库相关)
2. MTV
1.django独有:M(model:用类建表)、T(tempalte:HTML模板) 、V(views:业务逻辑函数)
M(model) : models
T(tempalte) : views
V(views): controller
二、CSRF
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
-