2

这是我的 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 and charlietfl 评论说“至于 ajax 错误处理。如果登录失败......使用真正的 REST 方法会发回 401 status 然后会触发您的 ajax 错误处理程序”,这就是为什么我在登录失败时不想要 200 OK 的原因。

4

1 回答 1

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')

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

于 2015-07-24T05:40:06.520 回答