Django CSRF令牌丢失和API

时间:2017-07-12 19:39:51

标签: django django-rest-framework django-csrf

我正在使用django 1.11.2和rest-framework 3.6.3,并且在向API发送反应表单时总是会出现关于csrf令牌丢失的错误。令人讨厌的是,它似乎是我唯一的测试人员/帮助者(他是PC脑筋,这就是他测试的原因),而不是我。

我只能在私密浏览中重现这种情况,即使我在视图上设置了ensure_csrf_cookie,CSRF cookie也不会出现。任何想法如何解决这个问题?

这是我的设置:

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django.contrib.flatpages',

'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'drf_braces',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.google',
'allauth.socialaccount.providers.linkedin_oauth2',
'rest_auth.registration', (...)

MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

'django.middleware.security.SecurityMiddleware',
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
'project.middleware.TimezoneMiddleware'

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.BasicAuthentication',
    'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_THROTTLE_CLASSES': (
    'rest_framework.throttling.AnonRateThrottle',
    'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
    'anon': '60/minute',
    'user': '60/minute'
}

}

我试过使用rest-framework的api_view装饰器以及确保csrf装饰器。什么都没有帮助。视图是基于类的(来自FormView),而post方法不起作用,如下所示:

from rest_framework.decorators import api_view
from django.utils.decorators import method_decorator

#@method_decorator(ensure_csrf_cookie)
@api_view(['POST','GET'])
def post(self, request, *args, **kwargs):
    (...)

使用通常的django方式在反应代码中检索csrf令牌。为此,我构建了一个csrf react组件,如下所示:

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 = $.trim(cookies[i]);
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(
                  cookie.substring(name.length + 1)
                  );
                break;
            }
        }
    }
return cookieValue;
}


var DjangoCSRFToken = React.createClass({
  getInitialState: function() {
    var csrftoken = getCookie('csrftoken');
    //saving to FormStore, to be send later to the server
    this.props.setValue('csrfmiddlewaretoken',csrftoken);
    return {};
  },

  render: function() {

    var csrftoken = getCookie('csrftoken');

    return React.DOM.input(
      {type:"hidden", name:"csrfmiddlewaretoken", value:csrftoken}
      );
  }
});

0 个答案:

没有答案