Django中关于csrf_token
的问题和解决
目录
在需要发送POST
请求的html文件中引入下面的js代码, 我为其命名为get_csrf_token.js
, 我下面的几个处理都需要使用到这一js代码文件
$(() => {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
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", getCookie('csrftoken'));
}
}
});
});
1. 在form
表单中加上{% csrf_token %}
2. 使用装饰器的方法,可以不用在form
表单中添加上{% csrf_token %}
了
(当然了这种方法与上面在每个form表单中添加上csrf_token 没有什么区别,都是只针对单个的)
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie
class LoginView(View):
"""
登录
url: /user/login/
"""
@method_decorator(ensure_csrf_cookie) # 获取csrf_token值
def get(self, request):
"""
响应登录get请求
返回登录页面
"""
return render(request, 'user/login.html')
def post(self, request):
"""
登录功能
:param request:
:return:
"""
pass
3. 使用中间件,为每个请求都获取到token
(使用这个方法,所有的表单都不需要在form标签中添加上{% csrf_token %}
了)
- 定义一个中间件
# 文件路径,如为: utils/my_middleware.py
from django.utils.deprecation import MiddlewareMixin
from django.middleware.csrf import get_token
class GetCsrfTokenMiddleware(MiddlewareMixin):
def process_request(self, request):
"""执行视图之前被调用,在每个请求上被调用"""
get_token(request)
- 在settings.py 中找到
MIDDLEWARE
, 注册中间件
# 中间件
MIDDLEWARE = [
...
'utils.my_middleware.GetCsrfTokenMiddleware'
# '中间件文件路径.中间件文件名.定义的中间件类'
]