Documentation: https://docs.djangoproject.com/en/1.7/topics/auth/default/#django.contrib.auth.login
When you’re manually logging a user in, you must call authenticate() before you call login(). authenticate() sets an attribute on the User noting which authentication backend successfully authenticated that user (see the backends documentation for details), and this information is needed later during the login process. An error will be raised if you try to login a user object retrieved from the database directly.
So why exactly is authenticate
and login
2 separate functions? From what I understand, authenticate
just verifies the login information. login
will take the user object and set the cookies. The only reason I can think they are separate is because maybe you can put different user objects in, say the user had 2 accounts merged. Maybe you want to verify the email address first. Is that why they are separate functions and login
doesn't wrap authenticate
?
In simple terms,
Authenticate refers to verifying the user credentials
Whereas login refers to creation of a user session once the user credentials has been verified(authenticated)
This is a matter of the single responsibility principle: a method should do one logical thing. As you noted yourself, these two steps ate logically distinct:
authenticate
just verifies the login information.
login
will take the user object and set the cookies
To further clarify, authentication is a one-time check,
and doesn't imply a login session.
A login session implies some period of time during which the user is free to perform various restricted activities without repeated authentication checks.
Sometimes you may need to authenticate users (verify they are who they say they are) without logging them in.
If these two functionalities were combined into one,
you wouldn't be able to do that,
even if you just wanted to do a one-time check,
you would have to log them in, creating a session,
which wouldn't make sense.
Since these are clearly distinct purposes,
it makes perfect sense to have two methods.
The separation also makes testing easier. If you write an new authentication backend, you would want to be able to test if the authentication step alone is working or not, without having to worry about how the whole login system works, which is not the responsibility of your backend.
Decomposing methods into their smallest logically independent elements is the sensible thing to do, with many benefits.