Django user is_authenticated vs. is_active: when should I use one or the other?

After reading the documentation, I still don't fully grasp the difference between these two User methods: is_active and is_authenticated.

Both are returning a boolean. While is_authenticated is read-only (and you get an error if you try to set it), is_active can be modified and for instance you can set it to False instead of deleting account.

Running these commands, will de-activate a user:

>>> from django.contrib.auth.models import User
>>> u = User.objects.get(pk=10) # get an arbitrary user   
>>> u.is_active
True
>>> u.is_active = False # change the value
>>> u.save() # save to make effective
>>> u.is_authenticated
True

Now, this user is still authenticated but is not able to login anymore.

The login view uses authenticate(). What is actually happening that the login for a de-activated user fails?

if request.method == 'POST':
    username = request.POST['username']
    password = request.POST['password1']
    user = authenticate(request, username=username, password=password)
    if user is not None:
        login(request, user)

To verify the credentials you use authenticate() which returns a User object in case of success or None otherwise. I guess it returns None in case the supplied credentials are correct but is_active is False.

In addition, the Jinja block {% if user.is_authenticated %} evaluates as false if is_active is False, which is confusing when I think that user.is_authenticated is True and read-only.

Question recap:

When a user is de-activated, is_active is false and is_authenticated is (always) true. What is actually authenticate() checking if the user is not active but authenticated? Is it because is_authenticated is an alias for checking that the user exists? But then why is {% user.is_authenticated %} even false?

Upvotes: 1

Views: 1289

Answers (1)

deceze
deceze

Reputation: 522597

is_active is an attribute on user accounts which can be flipped on and off. You can do that in the admin interface, or programmatically. Only active users are allowed to log in. I.e. you can use the is_active flag to prevent a user from logging in without needing to change their password, delete their account, or do anything else drastic.

is_authenticated is an attribute of the specific user class being used. If you have actual User objects, their is_authenticated attribute is always true; it's a statically set attribute on the User class.

The is_authenticated attribute is relevant only on user objects on requests:

def view(request):
    if request.user.is_authenticated:
        ...

If the user of the request was not authenticated, request.user would not be a User object, but an AnonymousUser object, whose is_authenticated attribute is always False. The idea here is that request.user always exists, regardless of whether a user is currently authenticated or not. This means you don't need to write code like if request.user is not None and request.user..... You can always expect a user object to exist, and you can distinguish between authenticated and unauthenticated (anonymous) users with the is_authenticated attribute.

Upvotes: 5

Related Questions