每当我在基于Django/Piston的REST API应用程序中遇到验证失败时,我目前正在返回401 Unauthorized .看过HTTP状态代码注册表后 我不相信这是验证失败的合适代码,你们都推荐什么?
更新:上面的"验证失败"表示应用程序级别数据验证失败,即错误指定日期时间,虚假电子邮件地址等.
我正在实现一个简单的注册/登录模块.
在测试用户凭据时,我开始考虑哪种HTTP状态代码适用于用户发送带有错误凭据的请求的情况.
起初,我认为401 Unauthorized是一个不错的状态代码,但是当用户试图在未经授权的情况下获取某些资源时,它似乎会更好.
之后,我切换到409冲突
此代码仅在预期用户可能能够解决冲突并重新提交请求的情况下才允许.
所以,朋友们,请给我一个建议,应该使用哪个状态代码.
我发现了很多关于HTTP状态代码含义的答案和解释。我的问题特别是关于对登录端点的POST请求,该请求例如要求提供用户名和密码以及提供不正确用户名和密码的情况。
一些想法:
400错误的响应 我认为此代码不合适,因为它表示该请求在语法上是不正确的,并且服务器无法理解,此处不是这种情况。登录数据在语义上是不正确的。
401未经授权 这对我来说是棘手的部分。如果401仅出现在需要身份验证标头的请求上,那么这是不正确的。但是,如果401可能出现在所有要求身份验证的请求上(作为标头或在正文中),则401是候选对象。
403禁止 通常,如果用户已经通过身份验证并为系统所知,但请求了不允许其访问的资源,则返回403。在登录之前,绝对不会对用户进行身份验证。我不知道未经身份验证的用户是否有403的语义。
得知答案或听到您的想法我很高兴。
这是我的 URLs.py:
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
Run Code Online (Sandbox Code Playgroud)
我的主页上有一个表单,用户可以在其中键入用户名和密码。当提交按钮被点击时,AngularJS 使用用户对象(用户名和密码)向“api-auth/login/”发送一个 POST 请求:
$http.post("/api-auth/login/", self.loginuser)
.error(function(data, status, headers, config) {
console.log(data);
});
Run Code Online (Sandbox Code Playgroud)
当用户提交不正确的用户名和密码(用户名和密码不存在或不匹配)时,Django Rest Framework 返回 200 OK 而不是 204 No Content、404 或 401 Unauthorized(在这篇文章中,它说 401是要返回的正确状态代码:如果用户尝试使用不正确的用户名/密码但格式正确登录,要返回的适当 HTTP 状态代码是什么?)。
根据这里:http : //www.w3.org/Protocols/rfc2616/rfc2616-sec9.html在第 9.5 节 POST 中,它说“在这种情况下,200(OK)或 204(无内容)是适当的响应状态,取决于响应是否包含描述结果的实体。”
如果数据存在,我会处理错误并记录数据(我在 JS 中做了 console.log(data)),但没有记录数据,这意味着(据我了解)没有数据发送/响应不包含描述的实体结果。
那么 DjangoRestFramework 为什么会返回 200 而不是 204 No Content(或者 404 或 401,根据我链接到的其他 SO 帖子应该返回什么)?
这是一个非常直接的测试,但我似乎无法做到正确.
我想检查哪些用户可以登录并执行操作(它是更大的测试套件的一部分),但第一步导致一些问题.
class SuperUserTest(TestCase):
def setUp(self):
self.client = Client()
self.su = User.objects.create_superuser('super','','the_correct_password')
def test_su_can_login(self):
response = self.client.post(reverse('django.contrib.auth.views.login'),
{'username': 'super', 'password': 'the_wrong_password'})
self.assertEqual(response.status_code,401)
# Success redirects to the homepage, so its 302 not 200
response = self.client.post(reverse('django.contrib.auth.views.login'),
{'username': 'super', 'password': 'the_correct_password'})
self.assertEqual(response.status_code,302)
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,我得到:
(my_app)00:20 ~/my_app (master)$ ./manage.py test my_app.SuperUserTest
Creating test database for alias 'default'...
F
======================================================================
FAIL: test_su_can_login (my_app.SuperUserTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./my_app/tests.py", line 341, in test_su_can_login
self.assertEqual(response.status_code,401)
AssertionError: 200 != 401
----------------------------------------------------------------------
Ran 1 test …Run Code Online (Sandbox Code Playgroud)