即使登录请求的凭据不正确,Django Rest Framework也会返回200 OK

时间:2015-07-24 02:25:03

标签: django django-rest-framework django-rest-auth

这是我的URLS.py:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^CMS/', include('CMSApp.urls')),
    url(r'^admin/', include(admin.site.urls)),
]

这是CMSApp / urls.py:

from django.conf.urls import url
from django.conf.urls import include
from CMSApp import views

urlpatterns = [
    url(r'^$', views.HomePageView.as_view()),
    url(r'^users$', views.user_list.as_view()),
    url(r'^users/(?P<pk>[0-9]+)$', views.user_detail.as_view()),
    url(r'^api-auth/', include('rest_framework.urls',
                                   namespace='rest_framework')),
]

我的HomePageView服务于此home.html页面:

<h3>Register</h3>
<form ng-submit="ctrl.add()" name="myForm">
    <label>Username</label>
    <input type="text" name="uname" ng-model="ctrl.user.username" required> 
    <label>Password</label>
    <input type="password" name="pwd" ng-model="ctrl.user.password" required>
    <label>Email</label>
    <input type="email" name="mail" ng-model="ctrl.user.email" required> 
    <input type="submit" value="Register"> 
</form>

<h3>Login</h3>
<form ng-submit="ctrl.loginUser()" name="myLoginForm">
    <label>Username</label>
    <input type="text" name="uname" ng-model="ctrl.user.username" required> 
    <label>Password</label>
    <input type="password" name="pwd" ng-model="ctrl.user.password" required>
    <input type="submit" value="Login"> 
</form>

<script>
angular.module("notesApp", [])
    .config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.xsrfCookieName = 'csrftoken';
        $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    }])

    .controller("MainCtrl", ["$http", function($http) {
    var self = this;
    self.users = {};
    var fetchUsers = function() {
        return $http.get("/CMS/users").then(function(response) { // get list of existing users
            self.users = response.data;
        }, function(errResponse) {
        console.error("Error while fetching users.");
        });
    };

    self.loginUser = function() {
        $http.post("/CMS/api-auth/login/", self.user)
        .error(function(data, status, headers, config) {
            console.log(data);
         })
        .then(fetchUsers);

        console.log("Success Login with ", self.user);
    };
    }]);
</script>

当我注册已经存在的用户时,Django会返回400 Bad Request错误,这很好,因为我在前端使用AngularJS来处理400状态代码。

问题是,当我尝试使用不正确的用户名和密码(不存在的用户名或不匹配的用户名和密码)登录时,Django会返回200 OK状态代码,这样我就可以[...在前端使用AngularJS跟踪问题。当我尝试使用不正确的用户名和密码登录时,任何想法为什么Django返回200 OK?当提交错误的用户名/密码时,如何让Django返回400?

编辑:这是我原来的帖子:Django Rest Framework + AngularJS not logging user in or throwing errors和charlietfl评论说#34;关于ajax错误处理。如果登录失败....使用真正的REST方法将发回401状态,然后激活你的ajax错误处理程序&#34;,这就是为什么我不想在登录失败时200 OK。

1 个答案:

答案 0 :(得分:1)

首先要理解的是,Django默认情况下不会强制执行身份验证。您可以使用auth模块注册用户并对其进行身份验证,但您必须明确保护您的视图。身份验证应用程序仅提供API供您使用,除非您使用这些API,否则它实际上不会保护任何内容。

任何未明确检查身份验证的视图都将向所有人开放。

当然,管理员要求您登录,但这是因为管理员应用程序的作者在其代码中包含了检查...

Django REST框架有自己的检查,所以只需要很少的编码,你只需要配置每个视图(参见文档):

http://www.django-rest-framework.org/api-guide/authentication/

对于您可能想要保护的任何其他视图,您需要添加一些检查。对于常规函数类型视图,视图上的@login_required装饰器是一种方法。由于您正在处理基于类的视图,请在此处查看Django文档:

https://docs.djangoproject.com/en/1.8/topics/class-based-views/intro/#mixins-that-wrap-as-view

检查登录状态的另一个选项是使用中间件类。这是我在当前系统中所做的事情,因为我们网站上的几乎所有内容都要求用户登录。因此,在中间件类中,我们检查是否request.user.is_anonymous。如果是,那么他们只能访问一小部分页面,如果他们不访问这些页面,我们会将其重定向到登录。中间件在任何视图之前运行,以便覆盖整个站点。

好的,现在我明白你想通过ajax请求实际登录用户,而不仅仅是检查他们的访问权限..你想要控制回复的内容,那么我建议你实现自己的观点用于登录服务。类似的东西:

class LoginView(View):
    def get(self, request, *args, **kwargs):
        user = auth.authenticate(
            username=request.GET.get('username'),
            password=request.GET.get('password'))

        # return whatever you want on failure
        if not user or not user.is_active:
            return HttpResponse(status=500)

        auth.login(request, user)
        return HttpResponse('OK')

我没有测试这段代码,但它应该非常接近。