2015-04-15 27 views
1

我已經在本地部署了一個帶有Django REST API框架的API。 我的移動應用程序是使用Ionic框架(使用AngularJS)開發的。Django和Angular POST請求 - CSRF失敗

在我的應用程序,當我想請求在阿賈克斯(POST方法),我有這樣的錯誤:

CSRF Failed: CSRF token missing or incorrect.

當我在Django的REST API集成項目要求我還沒有收到此錯誤。

我研究了網絡上的解決方案,但都沒有成功。

項目簡介:

Django的文件settings.py

MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware', 
'corsheaders.middleware.CorsMiddleware', 
'klipix.django-crossdomainxhr-middleware.OrganizationMiddleware', 
'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', 
) 

CORS_ORIGIN_ALLOW_ALL = True 
CORS_ALLOW_CREDENTIALS = True 

我用TokenAuthentication方法(http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication)。我django-crossdomainxhr-middleware.py文件:

class OrganizationMiddleware(object): 

def process_view(self, request, view_func, view_args, view_kwargs): 
header_token = request.META.get('HTTP_AUTHORIZATION', None) 
if header_token is not None: 
    try: 
    token = sub('Token ', '', request.META.get('HTTP_AUTHORIZATION', None)) 
    token_obj = Token.objects.get(key = token) 
    request.user = token_obj.user 
    except Token.DoesNotExist: 
    pass 

在我的應用我試圖添加此解決方案,但它沒有工作:

angular.module('starter', ['ionic']) 
.run(function($rootScope, $ionicPlatform, $http) { 

    $http.defaults.xsrfHeaderName = 'X-CSRFToken'; 
    $http.defaults.xsrfCookieName = 'csrftoken'; 

.config(function($stateProvider, $urlRouterProvider, $httpProvider) { 

    $httpProvider.defaults.withCredentials = true; 
    $httpProvider.defaults.xsrfCookieName = 'csrftoken'; 
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken'; 

請爲此提供了寶貴的投入。

+0

我收到了同樣的錯誤。你是如何在django rest api的離子應用程序中提供csrf令牌的? –

+0

由@Jakob Runge提供的答案是最準確的,請參閱.... –

回答

4

對我來說,這一點也適用角1.4:

var myApp = angular.module('myApp', []).config(function($httpProvider) { 
    $httpProvider.defaults.xsrfCookieName = 'csrftoken' 
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken' 
}); 
0

這適用於我。

.run(function run($http, $cookies){ 
    // For CSRF token compatibility with Django 
    $http.defaults.headers.common['X-CSRFToken'] = $cookies['csrftoken']; 
}); 
+0

不適用於我...您可以與我分享您的Django settings.py文件嗎? – tibeoh

+0

'ALLOWED_HOSTS = ['*']'我沒有一個自定義的中間件。但是我還在'DEFAULT_AUTHENTICATION_CLASSES'中使用了REST Framwork和'rest_framework.authentication.SessionAuthentication'。我不使用'CORS_ORIGIN_ALLOW_ALL'和其他'CORS'設置 –

2
angular.module('starter', ['ngCookies']) 
    .config(function ($httpProvider) { 
     $httpProvider.defaults.xsrfCookieName = 'csrftoken'; 
     $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken'; 
     $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 
    }) 
    .run(function run($http, $cookies){ 
     $http.defaults.headers.post['X-CSRFToken'] = $cookies['csrftoken']; 
}) 
0

您需要配置的角度$ HTTP和Django {{csrf_token}}。

在導入角度應用程序和控制器後,將以下腳本添加到您的html中。

<script> 
    var app = angular.module('my_app'); 

    app.config(['$httpProvider', function($httpProvider) { 
     $httpProvider.defaults.headers.common['X-CSRFToken'] = '{{ csrf_token|escapejs}}'; 
    }]); 
</script>