【问题标题】:403 error with angular.js post and django rest frameworkangular.js post和django rest框架出现403错误
【发布时间】:2015-10-12 16:55:42
【问题描述】:

我正在尝试使用前端的 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>

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

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 标头:

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."}

【问题讨论】:

  • 您需要在 headers 中发送 csrf 令牌。
  • 请检查我的编辑。谢谢
  • 您是否在请求负载的标头中看到了 csrf 令牌?您可以签入开发者工具。
  • @ZackTanner 是的,我可以看到它。
  • 不是响应,是请求。在那里,寻找标题X-CSRFToken

标签: angularjs django rest django-rest-framework http-status-code-403


【解决方案1】:

根据我的阅读,CRSF 参数需要在 config 函数中应用:

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

【讨论】:

  • 并且配置附加到$httpProvider 而不是$http
  • 这没有帮助,{$ 不再被解释。
【解决方案2】:

响应您的编辑,消息: {"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 作为权限,您可以执行以下操作来将这些权限限制为发布路由。这是一个例子:

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。

【讨论】:

  • 谢谢@ZackTanner。我确定问题是围绕这些问题。但很遗憾,您提供的内容还没有解决问题。
  • 尝试将 permission_classes 设置为 AllowAny。首先导入该权限from rest_framework.permissions import AllowAny,然后将permission_classes 更新为permission_classes = (AllowAny,)
  • 成功了!非常感谢 !但是拥有 AllowAny 是否不危险,为什么它不适用于 IsAuthenticated ?谢谢!
  • 可能是因为用户未通过身份验证,因此他们被拒绝访问。此特定视图似乎用于对用户进行身份验证,因此 IsAuthenticated 将始终为 false,直到该用户通过身份验证。看看这篇文章:richardtier.com/2014/03/06/110——实际上我在创建 auth viewset 时将其用作参考。
  • 没问题。我用一个可能更安全的解决方案更新了我的帖子,请随时查看。
猜你喜欢
  • 2013-10-20
  • 2020-08-14
  • 2019-02-22
  • 2021-09-25
  • 2014-04-13
  • 2016-02-17
  • 2015-03-23
  • 2019-05-17
  • 2015-01-26
相关资源
最近更新 更多