使用csrf_token 的原因是为了防止CSRF攻击,它会生成一个安全的令牌(token),提高网站安全性。
Django 自带用于全局 csrf_token 验证的中间件 django.middleware.csrf.CsrfViewMiddleware。
1、在Django的settings文件中:
settings文件中配置完毕后,全局向后台的 POST 请求都会使用csrf_token 验证。
2、views文件:
默认所有的post请求都是需要进行csrf 验证的,如果不想进行 csrf 保护可以加上装饰器 @csrf_exempt
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def server_error(request):
return render(request, '500.html')
return 的时候最好使用 render() 而不要用 render_to_response()
使用 return render_to_response(‘xxx.html’)
会报错:
UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value.
This is usually caused by not using RequestContext.
搜索了一下,有的解决方法是添加了 context_instance :
from django.template import RequestContext
return render_to_response('xxx.html', locals(),context_instance = RequestContext(request))
但是部分版本的Django render_to_response() 没有这个参数,通用的还是换成 :
from django.shortcuts import render
return render(request,'xxxx.html',local())
3、模板文件中
所有的 post请求form下添加 {% csrf_token %}
< form method="post" >
{% csrf_token %}
...
form >
csrf_token 验证只用于post,get不使用。
{% csrf_token %}的实际作用是在form下生成了一个 type为hidden 的name 为csrfmiddlewaretoken 的 input框。里面存放着用于csrf验证的随机码:
4、ajax请求(post),需要在data中传入csrfmiddlewaretoken 的值
这个值可以从 cookie 中获取
var csrf_token = document.cookie.replace(/(?:(?:^|.*;\s*)csrftoken\s*\=\s*([^;]*).*$)|^.*$/, '$1');
$.ajax({
url: '/url/',
type: "post",
data: {
'username':'username',
'password': 'password',
'csrfmiddlewaretoken':csrf_token
},
success: function (data) {
}
});
或者给多个 ajax请求统一配置(这个用法不太确定,实际用了之后也没报错):
$(function () {
var csrf_token = document.cookie.replace(/(?:(?:^|.*;\s*)csrftoken\s*\=\s*([^;]*).*$)|^.*$/, '$1');
$.ajaxSetup({data: {"csrfmiddlewaretoken": csrf_token}});
});
由于我的ajax请求中,有的请求使用的是FormData,配合上面的 ajaxSetup,可以单独针对这类请求做以下处理:
var formData = new FormData();
formData.append("csrfmiddlewaretoken", csrf_token);