2015-04-15 24 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>