30_Django中关于使用ajax发送请求中`csrf_token`的问题和解决

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 %} 了)

  1. 定义一个中间件
# 文件路径,如为: 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)
  1. 在settings.py 中找到 MIDDLEWARE, 注册中间件
# 中间件
MIDDLEWARE = [
    ...
    'utils.my_middleware.GetCsrfTokenMiddleware'
    # '中间件文件路径.中间件文件名.定义的中间件类'
]
原文地址:https://www.cnblogs.com/nichengshishaonian/p/11631614.html