angular.js post 和 django rest 框架的 403 错误

403 error with angular.js post and django rest framework

我正在尝试制作一个非常简单的登录表单,在前端使用 angular.js,在后端使用 api。这是 html 一侧的表格:

<form action="" method="post">
    {% csrf_token %}
    <div class="modal-body">
        <div class="form-group">
            <label for="login-username" class="control-label">Email:</label>
            <input type="text" class="form-control" name="username" id="login-username" ng-model="loginData.email" required>
        </div>
        <div class="form-group">
            <label for="login-password" class="control-label">Password:</label>
            <input type="text" class="form-control" name="password" id="login-password" ng-model="loginData.password" required>
        </div>
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary" ng-click="login()">Login as {$ loginData.email $}</button>
    </div>
</form>

这是我的 angular 控制器(注意:我知道这里没有问题,因为我有一个非常相似的寄存器功能,工作正常):

mainApp.controller("mainCtrl", function($scope, $http) {
    $scope.loginData = {"email":"bernard@mail.com","password":"pass"};
    $scope.login = function() {
        return $http.post('/api/v1/auth/login/', 
            $scope.loginData
        ).success(function(data, status){
            alert("success : "+status);
            console.log(data);
        }).error(function(data, status){
            alert("error : "+status);
        });
    }
});

这是我的 angular 应用程序,其中包含 csrf headers :

var mainApp = angular.module("mainApp", []).config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('{$');
    $interpolateProvider.endSymbol('$}');
}).run(run);


function run($http) {
    $http.defaults.xsrfHeaderName = 'X-CSRFToken';
    $http.defaults.xsrfCookieName = 'csrftoken';
}

在 django 方面,我有一个登录视图,它非常适合 get 而不是 post 方法。这就是我迷路的地方。

class LoginView(views.APIView):
    """
    View for login user
    """
    queryset = BaseUser.objects.all()

    def get(self, request, format=None):
        print("get_login098765") # THIS IS PRINTED PERFECTLY
        return Response()

    def post(self, request, format=None): #THIS THROWS 403 ERROR
        print("post_login098765") #THIS IS NOT PRINTED
        return Response()

我错过了什么?谢谢!

编辑:

我收到一个名为 login 的文件,其中包含:{"detail":"Authentication credentials were not provided."}

据我了解,需要在配置函数中应用 CRSF 参数:

var mainApp = angular.module("mainApp", []).config(function($interpolateProvider, $httpProvider) {
    $interpolateProvider.startSymbol('{$');
    $interpolateProvider.endSymbol('$}');
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
}).run(run);

为回应您的编辑,消息: {"detail":"Authentication credentials were not provided."} 由 Django REST Framework 抛出并且与您对该 ViewSet 的权限有关。我建议看看 http://www.django-rest-framework.org/api-guide/authentication/

这可能包括将默认身份验证 类 添加到您的设置文件,如下所示:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    )
}

或者基于视图,像这样:

from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated

class LoginView(api.APIView):
  authentication_classes = (SessionAuthentication, BasicAuthentication)
  permission_classes = (IsAuthenticated,)
  [...]

更新:由于使用 AllowAny 作为权限有效,您可以执行以下操作将这些权限限制为 post 路由。这是一个例子:

class LoginView(api.APIView):
  queryset = BaseUser.objects.all()

  def get_permissions(self):
      if self.request.method == 'POST':
          return (permissions.AllowAny(),)

      return (permissions.IsAuthenticated(),)

这将覆盖此端点上 POST 请求的权限,并默认为其他路由的 IsAuthenticated。