This is a pretty straight forward test, but I can't seem to get it right.
I want to check which users can login and perform actions (it's part of a larger suite of tests), but the very first step causes some issues.
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)
When I run the test I get:
(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'...
Why is django returning HTTP code 200 when I incorrectly login?
For additional context, here is how I'm managing the login/logout urls:
urlpatterns = patterns('',
# Examples:
url(r'^accounts/login/?$', 'django.contrib.auth.views.login'),
url(r'^accounts/logout/?$', 'django.contrib.auth.views.logout',
{'next_page': '/'}),
There's some debate in the web community about what the right response to a credentials failure is. (For example, here's a Wordpress ticket about switching from 200 to 401.) Django chooses to return a 200 response along with the re-rendered form.
In my opinion this is the right approach. A 401 or 403 response indicates that the user doesn't have permission to access the resource (URL). But in this case the resource is the login point, and you don't need credentials to access that; by definition it's available to all users. So essentially this case is no different from any other form validation—the server is checking the inputs it was sent, and if they're invalid it returns a 200 response along with the form and an error message.
I've just had a look through the Django source code and the reason why is in this function after line 52. If the form is invalid, the login view returns a TemplateResponse, simply returning to the same page and rendering the form with the errors.
来源:https://stackoverflow.com/questions/25839434/django-login-with-wrong-credentials-returns-200-not-401