Django身份验证:CSRF失败

时间:2016-02-01 09:34:17

标签: javascript python angularjs django django-rest-framework

有时我无法登录我的应用程序。

身份验证由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

2 个答案:

答案 0 :(得分:2)

您为什么使用$httpProvider.defaults.headers.common['X-CSRFToken'] = getCookie('csrftoken');?我不是AngularJS专家,但不应该需要这条线。

这是Django documentation所说的:

  

如果您使用的是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正在发挥作用。

答案 1 :(得分:0)

如果我没弄错,Django的CSRF有一个他们工作的时间表。

我不时会遇到这个问题并刷新表格,因此CSRF对我有用。