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

时间:2015-09-22 23:59:01

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

这是我的URLs.py:

url(r'^api-auth/', include('rest_framework.urls',
                               namespace='rest_framework')),

我的主页上有一个表单,用户可以在其中键入用户名和密码。单击提交按钮时,AngularJS会使用用户对象(用户名和密码)向“api-auth / login /”发送POST请求:

$http.post("/api-auth/login/", self.loginuser)
    .error(function(data, status, headers, config) {
        console.log(data);
     });

当用户提交错误的用户名和密码(用户名和密码不存在或不匹配)时,Django Rest Framework将返回200 OK而不是204 No Content,404或401 Unauthorized(在此帖子中,它说401是要返回的正确状态代码:What's the appropriate HTTP status code to return if a user tries logging in with an incorrect username / password, but correct format?)。

根据这里:{9.5} POST中的http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html,它说“在这种情况下,200(OK)或204(No Content)是适当的响应状态,具体取决于响应是否包含描述结果的实体。“

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

那么为什么DjangoRestFramework会返回200而不是204 No Content(或者404或401,根据我链接的其他SO帖子应该返回的内容)?

3 个答案:

答案 0 :(得分:3)

如果查看DRF's source,您会看到它使用Django自己的登录/注销视图。因此,这个问题与Django的表单处理本身有关。这里的a question与Django本身有关。

答案 1 :(得分:3)

以我的拙见,您将业务概念与协议问题混合在一起。

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

因此,毕竟,当您实际发生业务层错误(用户根据您的数据库输入的值不正确)时,您尝试记录应用程序错误。得到它?

答案 2 :(得分:1)

你的问题中有几件事情混杂在一起。首先,您使用的技术观点,以及您解释答案的方式。

1)观点

这是一个快速的。您可以通过向/api-auth/login/ DRF的可浏览API 的登录视图发送数据来使用该视图。这个视图实际上是Django的auth应用程序(django.contrib.auth.views.login)附带的视图,假设它正在处理用户,手动浏览API。

即:使用GET调用它构建一个空的html表单,使用POST发回表单将触发表单验证,这可能会以重新显示的形式结束(200 Ok with a包含的文件),或要发回的重定向(302找到空内容)。

这就是你的数据为空的原因:服务器发送一个HTML文档,而你的angular可能试图解析一些JSON对象。

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

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

2)文档与请求

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

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

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

    这可能有意义,但仅限于您有两层身份验证的环境中。在第二层登录请求通过之前,您需要具有对第一层有效的身份验证凭据。在这种情况下,如果您尝试使用第二层登录而未被第一层识别,则可以获得401。

    那么,REST如何适应?

    REST的概念,当应用于HTTP时,是尝试匹配请求级语义和文档级语义。它非常适合,因为每个REST概念都有匹配的HTTP谓词,HTTP可缓存,客户端服务器,......和...... 无状态

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

    1. 我们对某个端点进行身份验证(登录/密码,质询,oauth等)。
    2. 端点返回一些授权令牌
    3. 我们会向服务器发送每个下一个请求的授权令牌。
    4. 但事实是,每个请求都必须由服务器授权。也就是说,服务器将始终通过授权请求开始,然后再查看内部的内容。如果此步骤失败,则401是一个充分的响应。

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

      那么,如果选择不这样做,哪些错误代码是合适的?嗯,你可以选择几种:

      • 200好的。登录请求已成功处理并产生错误消息,这是一个包含结果的文档。然后,您的脚本将读取文档(例如,可能是JSON对象),以查看它是否有错误或授权令牌。
      • 204没有内容。登录请求已成功处理,但没有产生任何内容,当然也没有授权令牌。奇怪的选择,但是正确。
      • 400错误请求。登录请求未成功处理。

      唯一确定的是,401不是一个选项。 401意味着您不允许尝试登录。并非登录失败。