Django Rest Framework,CSRF和Vue.js

时间:2016-03-09 01:18:29

标签: django django-rest-framework vue.js

我正在尝试使用Vue.js对我使用Django Rest Framework创建的REST Api执行一些POST方法。问题是,我发帖时遇到CSRF Failed: CSRF token missing or incorrect.错误。但是我可以看到csrf cookie,它被添加到标题中。

这是我的设置:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
        'rest_framework.permissions.DjangoModelPermissions'
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication'
    )
}

这是我的Vue.js配置:

var csrftoken = Cookies.get('csrftoken');
Vue.http.headers.common['HTTP_X_CSRFTOKEN'] = csrftoken;

这是发送的标题的相关部分:

Cookie:djdt=hide; tabstyle=raw-tab; sessionid=1gl533mrneudxw3l9l2vg0ja1yowwmeo; csrftoken=dN85bhztB1oVRov87BsUrWTM29Ff9sjn
Host:127.0.0.1:8000
HTTP_X_CSRFTOKEN:dN85bhztB1oVRov87BsUrWTM29Ff9sjn
Origin:http://127.0.0.1:8000
Referer:http://127.0.0.1:8000/agencies/6/add-profiles/

如您所见,Cookie.csrf和HTTP_X_CSRFTOKEN标头匹配

我真的很难过。有什么建议吗?

2 个答案:

答案 0 :(得分:8)

所以我发布这个作为回答问题的答案。

问题是因为根据请求发送了错误的CSRF标头名称。根据文件:

  

与request.META中的其他HTTP标头一样,收到标头名称   通过将所有字符转换为来自服务器的规范化   大写,用下划线替换任何连字符,并添加   名称的'HTTP_'前缀。例如,如果您的客户发送了   'X-XSRF-TOKEN'标题,设置应为'HTTP_X_XSRF_TOKEN'。

此外,我在这里留下my question的引用,它累积了一些可能导致Django CSRF Failed: CSRF token missing or incorrect.错误的问题。

答案 1 :(得分:1)

从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('http://'+document.location.host+'/api//',{params: {foo: 'bar'}}, {headers: {"X-CSRFToken":csrftoken }}).then(function (response) {
            this.response = response.data;
        },
        function (response) {
            console.log(response);
        });