[英]Django authentication : CSRF Failed
有时我无法登录我的应用程序。
身份验证由Django API处理。
但是有时它在结果对象中返回403错误,并带有以下值:
responseText: "{"detail":"CSRF Failed: CSRF token missing or incorrect."}"
但是在我的应用程序中,我有:
angular.module('app')
.config(function(ezLayoutProvider, $httpProvider) {
ezLayoutProvider.register(layoutName, {templateUrl: './main.html'});
ezLayoutProvider.setDefault(layoutName);
var getCookie = function(cookieName) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, cookieName.length + 1) === (cookieName + '=')) {
cookieValue = decodeURIComponent(cookie.substring(cookieName.length + 1));
break;
}
}
}
return cookieValue;
};
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
$httpProvider.defaults.headers.common['X-CSRFToken'] = getCookie('csrftoken');
console.log($httpProvider.defaults.headers.common);
})
并且控制台显示在我尝试登录之前正确设置了令牌。
奇怪的是,一旦我从浏览器中清除了cookie并缓存了,它就起作用了。
所以我猜想它与Django的会话有某种关系?
这是我的settings.py的一部分:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.DjangoModelPermissions',
),
}
REST_PROXY = {
'HOST': 'http://localhost:5000'
}
CORS_ORIGIN_ALLOW_ALL = True
AUTHENTICATION_BACKENDS = (
'auth.ldap.LDAPBackendFR',
'auth.ldap.LDAPBackendUS',
'auth.ldap.LDAPBackendHK',
'auth.ldap.LDAPBackendIN',
'django.contrib.auth.backends.ModelBackend',
)
另一个奇怪的地方是,它似乎也可以使用:
Object {Accept: "application/json, text/plain, */*", X-Requested-With: "XMLHttpRequest", X-CSRFToken: null}
作为$httpProvider.defaults.headers.common
。
为什么要使用$httpProvider.defaults.headers.common['X-CSRFToken'] = getCookie('csrftoken');
? 我不是AngularJS专家,但是不需要这一行。
这就是Django文档所说的:
如果您使用的是AngularJS 1.1.3及更高版本,则使用cookie和标头名称配置
$http
提供程序就足够了:$http.defaults.xsrfCookieName = 'csrftoken'; $http.defaults.xsrfHeaderName = 'X-CSRFToken';
据我了解,这就是您的代码的外观:
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/* Not needed, causes harm! */
/* $httpProvider.defaults.headers.common['X-CSRFToken'] = getCookie('csrftoken'); */
console.log($httpProvider.defaults.headers.common);
这也应该解释为什么使用X-CSRFToken: null
起作用。
如果我没记错的话,Django的CSRF有一个时间表。
我有时会遇到这个问题并刷新表格,因此CSRF确实为我工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.