我正在使用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}
);
}
});