首页 > 解决方案 > 设置 Django CSRF Coo​​kie

问题描述

我使用 React 作为前面和 Django 作为后面。Httprequest失败,提示没有设置CSRF Coo​​kie。我遵循了 django 文档,我有以下代码:

var jQuery = require("jquery");
// using jQuery
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 = jQuery.trim(cookies[i]);
            // 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;
}

let header = new Headers({
  "X-CSRFToken": getCookie("csrftoken"),
  "Content-Type": "application/json; charset=utf-8",
  "Access-Control-Request-Headers": "*",
  "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS, PUT, DELETE, PATCH"
});

使用console.log(getCookie("csrftoken"));prints null,这让我相信 Django 没有设置 cookie。

我的中间件如下所示:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

在开发早期,我使用此视图进行测试:

@ensure_csrf_cookie
def token(request):
    if request.method == 'GET':
        return HttpResponse(status=204)
    else:
        return HttpResponseNotAllowed(['GET'])

这很好用,但是每次用户使用网站时调用它都感觉不是很干净。

失败的观点:

def loginView(request):
    if request.method == 'POST':
        username = json.loads(request.body.decode())['username']
        password = json.loads(request.body.decode())['password']
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user)
            return HttpResponse(status=200) #OK
        else:
            return HttpResponse(status=401) #DENIED
    else:
        return HttpResponseNotAllowed(['POST'])

我正在使用更多视图,如果我不提供 CSRF 密钥,它们也会失败。

标签: djangoreactjsfetchcsrf

解决方案


如评论中所述。我通过我的 jquery 传递了 csrf 令牌的值,如下所示。可能你也可以试试。

function getDetail(e){

  $.ajax({
      type: "POST",
      url: "/result/",
      data: {
            'search': $(this).text(),
            'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
      },
      dataType:'html',
      success: function(data) {
          # Do other stuff
      },
  });

};

推荐阅读