Angular 2 POST将403 CSRF错误发布到Django服务器

时间:2016-04-01 16:41:07

标签: angularjs django django-rest-framework

在尝试使用Angular 2发布到我的Django服务器时,我正在努力解决403 / CSRF问题。

我的服务器代码和我的Angular代码都在同一个127.0.0.1服务器上运行。

运行Angular代码时,服务器返回403 4612错误

我的Django View代码看起来像这样(我正在使用Django REST框架):

rom django.utils import timezone
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.models import User
from .models import Item, Seen, Keyword, Flag
from django.utils.decorators import classonlymethod
from django.views.decorators.csrf import csrf_exempt
from rest_framework import viewsets
from items.serializers import ItemSerializer, UserSerializer
from rest_framework.authentication import SessionAuthentication

class CsrfExemptSessionAuthentication(SessionAuthentication):
    def enforce_csrf(self, request):
        return  # To not perform the csrf check previously happening


class ItemViewSet(viewsets.ModelViewSet):
    queryset = Item.objects.all().order_by('-date_added')
    serializer_class = ItemSerializer
    authentication_classes = (CsrfExemptSessionAuthentication, )
    #permission_classes = [IsAccountAdminOrReadOnly]

    """
        Use the API call query params to determing what to return

        API params can be:

        ?user=<users_id>&num=<num_of_items_to_return>&from=<user_id_of_items_to_show>
    """

    def get_queryset(self):
        this_user = self.request.query_params.get('user', None)
        restrict_to_items_from_user_id = self.request.query_params.get('from', None)
        quantity = self.request.query_params.get('num', 20)

        if restrict_to_items_from_user_id is not None:
            
            queryset = Item.objects.filter(owner=restrict_to_items_from_user_id, active=True).order_by('-date_added')[0:int(quantity)]
        elif this_user is not None:
            
            queryset = Item.objects.filter(active=True, credits_left__gt=0).exclude(pk__in=Seen.objects.filter(user_id=this_user).values_list('item_id', flat=True))[0:int(quantity)]
        else:
            
            queryset = Item.objects.filter(active=True, credits_left__gt=0)[0:int(quantity)]

        return queryset

执行POST的我的Angular 2代码如下所示:

import {Injectable, Inject} from 'angular2/core';
import {Http, Headers, HTTP_PROVIDERS} from 'angular2/http';
import {UserData} from './user-data';
import 'rxjs/add/operator/map';


@Injectable()
export class ConferenceData {
  static get parameters(){
    return [[Http], [UserData]];
  }

  constructor(http, user) {
    // inject the Http provider and set to this instance
    this.http = http;
    this.user = user;
  }

  load() {

    // Example of a PUT item
    let body = JSON.stringify({ url: 'fred', item_type: 'P', owner_id: 2 });

    let headers = new Headers();
    headers.append('Content-Type', 'application/json');

    this.http.post('http://127.0.0.1:8000/api/items/', body, {
        headers: headers
      })
      .subscribe(
        data => {
          alert(JSON.stringify(data));
        },
        err => this.logError(err.json().message),
        () => console.log('Authentication Complete')
      );
  }
}

我发现CSRF问题真的难以掌握!

编辑:添加了CORS设置

我的CORS设置如下所示:

CORS_ORIGIN_ALLOW_ALL = True    
CORS_ORIGIN_WHITELIST = (
    'veeu.co',
    '127.0.0.1'
)
CORS_ORIGIN_REGEX_WHITELIST = ()
CORS_URLS_REGEX = '^.*$'
CORS_ALLOW_METHODS = (
    'GET',
    'POST',
    'PUT',
    'PATCH',
    'DELETE',
    'UPDATE',
    'OPTIONS'
)
CORS_ALLOW_HEADERS = (
    'x-requested-with',
    'content-type',
    'accept',
    'origin',
    'authorization',
    'x-csrftoken'
)
CORS_EXPOSE_HEADERS = ()
CORS_ALLOW_CREDENTIALS = False

1 个答案:

答案 0 :(得分:1)

您可以将令牌作为标头添加到您的ajax请求中,而不是禁用CSRF保护。请参阅the docs,特别是AngularJS的最后一节。

您可能必须使用csrf_ensure作为初始Django视图,以确保Django设置csrf cookie。