防⽌⽹站受第三⽅服务器的恶意攻击,csrf相当于在表达中增加了⼀个隐藏的input框,⽤于向服务器提交⼀个唯一的随机字符串⽤于服务器验证表单是否是本服务器的表单。
在settings中我们设置过这个中间件,默认是开启的,我们可以注释掉并不开启
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',
]
一、前后端不分离
我们开启的情况下可以设置一下我们的表单
<form action="" method="post">
{% csrf_token %}
<input type="text" name="username">
<input type="submit">
</form>
这样的话我们的表单会自动提交这个csrf,但是现在已经很少使用submit直接提交了,我们可以使用JS进行提交
<form method="POST" action="/csrf1.html">
{% csrf_token %}
<input id="username" type="text" name="username" />
<input type="submit" value="提交"/>
<a onclick="submitForm();">Ajax提交</a>
</form>
<script src="/static/jquery-1.12.4.js"></script>
<script>
function submitForm(){
var csrf = $('input[name="csrfmiddlewaretoken"]').val();
var user = $('#user').val();
$.ajax({
url: '/csrf1.html',
type: 'POST',
data: { "user":user,'csrfmiddlewaretoken': csrf},
success:function(data){
console.log('OK');
}
})
}
</script>
二、跨域问题
⼀个⽹站不能使⽤ajax来访问另⼀个⽹站的数据,这样的话会被浏览器给阻止,这个问题我们通常叫做跨域问题,哪怕是同一域名下的二级域名都不可以
域名的组成 http://www.google.com:80/index.html
http:// 协议
www 子域名
google 主域名
80 端口号
index.html 请求的地址
当协议、⼦域名、主域名、端⼝号中任意⼀个不相同时,都算不同的“域”,不同的域之间相互请求资源,就叫“跨域”。
三、前后端分离
对于前后端分离项目,我们就很难将生成的scrf字符串返回给前端,所以我们需要一个模块
pip install django-cors-headers
设置
#在INSTALLED_APPS⾥添加“corsheaders”
INSTALLED_APPS = [
'corsheaders',
]
#在MIDDLEWARE_CLASSES添加,这个中间件的位置不要改,否则会出bug
MIDDLEWARE_CLASSES = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]
# 处理跨域
# 添加允许执行跨站点请求的主机
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
# 授权进行跨站点HTTP请求的来源列表
CORS_ORIGIN_WHITELIST = [
'http://127.0.0.1',
'http://localhost',
]
# 允许的方法
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
# 发出实际请求时可以使用的非标准HTTP标头的列表
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)