这是一个非常直接的测试,但我似乎无法做到正确。
我想检查哪些用户可以登录并执行操作(它是更大的测试套件的一部分),但第一步会导致一些问题。
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)
当我运行测试时,我得到:
(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 in 1.180s
FAILED (failures=1)
Destroying test database for alias 'default'...
当我错误登录时,为什么django会返回HTTP代码200
?
有关其他上下文,以下是我管理登录/注销网址的方式:
urlpatterns = patterns('',
# Examples:
url(r'^accounts/login/?$', 'django.contrib.auth.views.login'),
url(r'^accounts/logout/?$', 'django.contrib.auth.views.logout',
{'next_page': '/'}),
答案 0 :(得分:6)
网络社区中存在一些关于对凭据失败的正确回应是什么的争论。 (例如,此处' sa Wordpress ticket关于从200
切换到401
。)Django选择返回200
响应以及重新呈现的表单。< / p>
在我看来,这是正确的方法。 401
或403
响应表示用户没有访问资源(URL)的权限。但在这种情况下,资源是登录点,您不需要需要凭据才能访问该资源;根据定义,它可供所有用户使用。所以基本上这种情况与任何其他表单验证没有什么不同 - 服务器正在检查它发送的输入,如果它们无效,它会返回200
响应以及表单和错误消息。< / p>
答案 1 :(得分:2)
我刚刚查看了Django源代码以及为什么在行52
之后的this函数中的原因。如果表单无效,login
视图将返回TemplateResponse
,只返回同一页面并呈现包含错误的表单。
答案 2 :(得分:1)
您可以通过以下方式轻松自定义此行为:
from django.contrib.auth.views import LoginView
class LoginView(LoginView):
def form_invalid(self, form):
response = super().form_invalid(form)
response.status_code = 401
return response
,您将需要更改相应的网址:
path("accounts/login/", views.LoginView.as_view(), name="login"),
path("accounts/", include("django.contrib.auth.urls")),