簡體   English   中英

Django驗證:CSRF失敗

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM