CSRF失败:CSRF令牌丢失或不正确

问题描述 投票:35回答:9

我使用Django 1.7和Django的REST的框架。

我做了我返回一些JSON数据把这个在我settings.py的API

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
    'DEFAULT_RENDERER_CLASSES': (
    #   'rest_framework.renderers.XMLRenderer',
    'rest_framework.renderers.JSONRenderer',
    #   'rest_framework.renderers.BrowsableAPIRenderer',
    )
}

当我做GET调用,它返回我所有的数据,但是当我试图用PUT / PATCH我得到:

--------Response Headers---------
Status Code: 403
Date: Wed, 29 Oct 2014 18:51:42 GMT
Vary: Cookie
Server: WSGIServer/0.1 Python/2.7.8
Allow: GET, POST, PUT, PATCH, HEAD, OPTIONS
X-Frame-Options: SAMEORIGIN
Content-Type: application/json
---------------------------------

--------Response Body-----------
{"detail": "CSRF Failed: CSRF token missing or incorrect."}
---------------------------------

这只是发生在我登录的,如果我是匿名的,我可以正确PUT / PATCH。

我曾尝试与@csrf_exempt和我的错误,我已经包括在设置中,rest_framework.permissions.AllowAny ...

我不知道发生了什么事。有谁知道是什么问题?

django django-rest-framework
9个回答
62
投票

当您使用SessionAuthentication,您正在使用Django的认证通常需要CSRF进行检查。 Django的REST框架强制执行此,只为SessionAuthentication,所以你必须通过CSRF令牌在X-CSRFToken头。

Django documentation提供检索CSRF令牌使用jQuery和请求发送它的更多信息。该CSRF令牌被保存为一个cookie称为csrftoken,你可以从HTTP响应,这取决于正在使用的语言检索。

如果你不能检索CSRF的cookie,这通常是你不应该使用SessionAuthentication的标志。我建议考虑TokenAuthenticationOAuth 2.0根据您的需要。


4
投票

这是我做过什么来解决这个问题,我包括CSRF令牌的形式和使用jquery /的javascrip得到了CSRF令牌这样当文件加载

var $crf_token = $('[name="csrfmiddlewaretoken"]').attr('value');

在包括它的jquery标题如下

 $.ajax({
            type: "POST",
            url: "/api/endpoint/",
            data: newEndpoint,
            headers:{"X-CSRFToken": $crf_token},
            success: function (newEnd) {
                console.log(newEnd);
                add_end(newEnd);
            },
            error: function () {
                alert("There was an error")
            }
        });

3
投票

1-搜索的Cookie头部

enter image description here

2-单独从所述的sessionid csrftoken

3-添加的X CSRFToken = {..在步骤2中提取的csrftoken ..}见下文

enter image description here 4-后再次


2
投票

我有类似的问题,我已经包裹着我的下csrf_exempt方法网址作为 -

from django.views.decorators.csrf import csrf_exempt

url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),

2
投票

我们有这个问题,它原来是邮差的错。他们被自动发送,我们并没有通过在头csrftokensessionid默认值。按照本教程帮着解决这个问题:https://avilpage.com/2019/02/django-tips-csrf-token-postman-curl.html


1
投票

我有一个类似的问题,我会包裹着csrf_exempt的意见,并仍然遇到错误。原来,我得到的URL错误,因此它被解析为一个“找不到”回调(这是不是从CSRF除外),并因此抛出异常之前我可以告诉的网址是错误的。


1
投票
// USING AJAX TO UPDATE DATABASE THROUGH REST API
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]);
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

var csrftoken = getCookie('csrftoken');

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", csrftoken);
        }
    }
});

0
投票

得到的cookie令牌:

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

var csrftoken = readCookie('csrftoken');

发送令牌头POST请求:

  this.$http.post(server,{params: {foo: 'bar'}}, {headers: {"X-CSRFToken":csrftoken }}).then(function (response) {
            this.response = response.data;
        },
        function (response) {
            console.log(response);
        });

0
投票

当您承载Apache服务器上Django的网站。与TokenAuthentication和SessionAuthentication Djando REST框架将得到

CSRF失败:CSRF令牌丢失或不正确

为了解决这个问题打开Apache的配置文件 - httpd.conf中添加以下行:

WSGIPassAuthorization On
© www.soinside.com 2019 - 2024. All rights reserved.