Deprecating User.is_anonymous ?

231 views
Skip to first unread message

Jeremy Lainé

unread,
Apr 2, 2016, 9:37:38 AM4/2/16
to django-d...@googlegroups.com
I have been working on solving #25847 (making User.is_authenticated a
property), and in the process I was wondering whether we want to keep
User.is_anonymous at all in the long run.

My reasoning is:

- the documentation makes it quite clear you should use
request.user.is_authenticated instead of request.user.is_anonymous

- there is no guarantee that request.user.is_authenticated !=
request.user.is_anonymous. This means a custom user model could make a
User both anonymous and authenticated (or neither) and we would end up
with rather surprising results depending on how authentication is
checked (using is_authenticated or is_anonymous).

Do we know of any custom user models with this unconventional behaviour?

Incidentally I found there is only one place were we django uses
.is_anonymous internally : django.contrib.auth.backends.ModelBackend,
all other places use user.is_authenticated as recommended in the
documentation.

Thanks in advance for your insights!
Jeremy

Tim Graham

unread,
Apr 2, 2016, 10:19:33 AM4/2/16
to Django developers (Contributions to Django itself)
Did you look into why both methods exist in the first place? I didn't know the reason.

is_anonymous() preceded is_authenticated(). The concern was that template code like this:

{% if not user.is_anonymous %}
Content for logged in users.
{% else %}
Content for non-logged in users.
{% endif %}

would show authenticated user content to anonymous users if the user variable didn't get put in the template context somehow [0]. User.is_authenticated() was added in Django 1.0 to mitigate this [1].

My concern is that if a project doesn't see the deprecation warnings and doesn't have adequate tests, they may not catch the fact that template code like:

{% if user.is_anonymous %}
Anonymous content
{% else %}
Authenticated content
{% endif %}

will start showing authenticated content to anonymous users after the method is removed. I think it's hard to argue that removing the method is work this risk. Maybe there's room to reduce confusion by deemphasizing usage of is_anonymous(). This might include removing its usage within Django itself and undocumenting it.

[0] http://thegarywilson.com/blog/2006/is_authenticated-vs-is_anonymous/
[1] https://github.com/django/django/commit/51705f60b1

Raffaele Salmaso

unread,
Apr 2, 2016, 10:30:04 AM4/2/16
to django-d...@googlegroups.com
On Sat, Apr 2, 2016 at 4:19 PM, Tim Graham <timog...@gmail.com> wrote:
My concern is that if a project doesn't see the deprecation warnings
What about having a new property like User.authenticated (or User.anonymous)?
User.is_anoymous and User.is_authenticated can be deprecate and removed from docs, leaving them in place for longer (django 3).

--

Jon Dufresne

unread,
Apr 2, 2016, 10:54:02 AM4/2/16
to django-d...@googlegroups.com
> Do we know of any custom user models with this unconventional behaviour?

FWIW, I have a project with the following code snippet:

---
class AuthenticatedAnonymousUser(AnonymousUser):
    def is_authenticated(self):
        return True


class AnonymousAuthenticationMiddleware(AuthenticationMiddleware):
    def process_request(self, request):
        response = super().process_request(request)
        if not response and not request.user.is_authenticated():
            if check_api_auth():
                request.user = AuthenticatedAnonymousUser()
else: response = HttpResponseForbidden()
return response
---

This is a small, internal, private project. Users can access the app though HTML pages by logging in (traditional web app) or through a user-less API. Many scripts use the API.

This allows views to check user.is_authenticated(). This passes for the AuthenticatedAnonymousUser, but the user is still treated as anonymous.

While I find this convenient, I could easily solve this some other way. But I wanted to point out that this use exists.

Cheers,
Jon

Reply all
Reply to author
Forward
0 new messages