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

Django Rest Framework - Why is a 200 status code returned when trying to login a user using incorrect credentials?

这是我的 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 return返回 200 OK 而不是 204 No Content、404 或 401未经授权(在这个 post 上,它说 401 是 return 的正确状态代码:)。

根据这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html 在第 9.5 节 POST,它说 "In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result."

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

那么为什么 DjangoRestFramework return 是 200 而不是 204 无内容(或 404 或 401,根据其他 SO post 应该 returned我链接到)?

如果你看 DRF's source you will see that it uses Django's own Login/Logout views. Therefore this is question would be more related to Django's form handling itself. Here's a question 那与 Django 本身有关。

以我的愚见,您在这里将业务概念与协议问题混为一谈。

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

所以,毕竟,当它实际上是业务层错误(用户根据您的数据库输入了错误的值)时,您正在尝试记录应用程序错误。明白了吗?

你的问题中有几件事混淆了。首先是您使用的技术观点,其次是您解释答案的方式。

1) 观看次数

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

也就是说:用 GET 调用它会构建一个空的 html 表单,用 POST 发回表单将触发表单验证,它可以以以下形式结束重新显示(200 Ok,包含文档),或发回重定向(302 发现内容为空)。

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

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

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

2) 文档与请求

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

  1. 请求的含义。
  2. 请求中所附文件的含义。

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

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

它可能有意义,但只有在您拥有两层身份验证的情况下。在允许您的第二层登录请求通过之前,您需要具有对第一层有效的身份验证凭据。在这种情况下,如果您尝试使用第二层登录而第一层无法识别,您可能会收到 401。

那么,REST 如何适应?

REST的概念,应用于HTTP时,就是尽量匹配请求级语义和文档级语义。它特别适合,因为每个 REST 概念都有一个匹配的 HTTP 动词,HTTP 是可缓存的,客户端-服务器,......和...... stateless.

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

  1. 我们对某个端点进行身份验证(login/password、质询、oauth 等等)。
  2. 端点returns一些授权令牌
  3. 我们将授权令牌与每个下一个请求一起发送到服务器。

但事实是,每个请求都必须经过服务器授权。也就是说,服务器总是先授权请求,然后再查看里面的内容。如果此步骤失败,401 是足够的响应。

步骤 #1 除外。此请求没有授权步骤。它必须被处理,login/password 必须被检索和检查,并且根据结果,服务器可能决定发回授权令牌。

那么,如果它选择不这样做,什么样的错误代码是合适的?那么,有几个你可以选择:

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

唯一可以确定的是,401 不是一个选项。 401 表示不允许您尝试 登录。不是登录失败