Angularjs Django Rest框架-为什么在尝试使用不正确的凭据登录用户时返回200状态码?

Angularjs Django Rest框架-为什么在尝试使用不正确的凭据登录用户时返回200状态码?,angularjs,django,django-rest-framework,django-rest-auth,Angularjs,Django,Django Rest Framework,Django Rest Auth,这是我的URL.py: url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), 我的主页上有一个表单,用户可以在其中键入用户名和密码。单击提交按钮时,AngularJS向“api auth/login/”发送一个POST请求,其中包含用户对象(用户名和密码): 当用户提交不正确的用户名和密码(用户名和密码不存在或不匹配)时,Dja

这是我的URL.py:

url(r'^api-auth/', include('rest_framework.urls',
                               namespace='rest_framework')),
我的主页上有一个表单,用户可以在其中键入用户名和密码。单击提交按钮时,AngularJS向“api auth/login/”发送一个POST请求,其中包含用户对象(用户名和密码):

当用户提交不正确的用户名和密码(用户名和密码不存在或不匹配)时,Django Rest Framework返回200 OK而不是204 No Content、404或401 Unauthorized(在本文中,它说401是要返回的正确状态代码:)

根据此处:在第9.5节文章中,它说“在这种情况下,200(确定)或204(无内容)是适当的响应状态,这取决于响应是否包含描述结果的实体。”

如果数据存在,我会处理错误并记录数据(我在JS中使用了console.log(data)),但没有记录数据,这意味着(据我所知)没有发送数据/响应不包括描述结果的实体


那么为什么DjangoRestFramework会返回200而不是204 No内容(或者404或401,根据我链接到的另一篇So文章,这是应该返回的内容)?

如果您查看一下,您会发现它使用Django自己的登录/注销视图。因此,这个问题将更多地涉及Django的表单处理本身。这是一个与Django本身相关的问题。

在我看来,您将业务概念与协议问题混为一谈

登录方法不应返回401(未经授权),因为它的先决条件是用户(显然)尚未授权/验证。因此,如果请求是以正确的方式发出的(从语法上讲),尽管用户凭据不正确(业务概念),响应应该是200(协议),也就是说,请求已被接受并正确处理。当然,响应主体将确定它是否成功登录


因此,毕竟,您正试图记录一个应用程序错误,而实际上它是一个业务层错误(用户根据您的数据库输入了不正确的值)。明白了吗?

在你的问题中,有好几件事混在一起了。首先是您使用的技术视图,其次是您解释答案的方式

1)视图

这很快。通过将数据发送到可浏览api的DRF登录视图,您使用的视图。此视图实际上是Django的
auth
应用程序(
Django.contrib.auth.views.login
)附带的视图,它假定它正在与用户打交道,手动浏览API

也就是说:使用
GET
调用它会构建一个空的html表单,使用
POST
发回表单将触发表单验证,这可能会导致表单被重新显示(200 Ok,包含文档),或者重定向被发回(302发现有空内容)

这就是为什么您的数据是空的:服务器发送一个HTML文档,而您的用户可能试图解析某个JSON对象

您使用的表单视图绝对不是从脚本调用的。这是可以做到的,但您需要相应地处理结果,这意味着分析返回的html页面以查找错误消息。乱七八糟的

如果您想从脚本轻松访问它,您应该构建自己的登录视图

2)文档与请求

在这里,您将处理两个不同的语义级别

  • 请求的含义
  • 请求中所附文件的含义
  • HTTP错误代码在请求上下文中是有意义的。它们发生在较低的层次。例如,返回401代码意味着“在执行此请求之前需要有效的身份验证凭据”

    在这里,这基本上意味着“在我处理您的登录请求之前,您必须拥有有效的身份验证凭据”

    这可能是有意义的,但只有在有两层身份验证的上下文中才有意义。在第一层允许第二层登录请求通过之前,您需要具有第一层的有效身份验证凭据。在这种情况下,如果您尝试在第一层无法识别的情况下使用第二层登录,则可以获得401

    那么,休息是如何适应的呢

    当应用于HTTP时,的概念是尝试匹配请求级语义和文档级语义。它特别适合,因为每个REST概念都有一个匹配的HTTP动词,HTTP是可缓存的,客户机-服务器。。。而且无状态

    无状态意味着HTTP和REST都没有登录的概念。登录是一种抽象,这通常意味着我们使用的工作流如下所示:

  • 我们对某个端点进行身份验证(登录/密码、质询、oauth等等)
  • 端点返回一些授权令牌
  • 我们将授权令牌与下一个请求一起发送到服务器
  • 但事实是,每个请求都必须由服务器授权。也就是说,服务器总是先授权请求,然后再查看内部内容。如果该步骤失败,401是适当的响应

    除了第1步。此请求没有授权步骤。必须对其进行处理,必须检索和检查登录名/密码,并且根据结果,服务器可能决定发回授权令牌

    那么,如果它选择不这样做,哪些错误代码是合适的呢?嗯,您可以从以下几个方面进行选择:

    • 200好。登录请求已成功处理并生成错误消息,下面是一个包含结果的文档。然后,脚本将读取文档(例如,可以是JSON对象)以查看它是否有错误或授权令牌
    • 204没有内容。登录请求
      $http.post("/api-auth/login/", self.loginuser)
          .error(function(data, status, headers, config) {
              console.log(data);
           });