Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django, request.user is always Anonymous User

Tags:

I am using a custom authentication backend for Django (which runs off couchdb). I have a custom user model.

As part of the login, I am doing a request.user = user and saving the user id in session. However, on subsequent requests, I am not able to retrieve the request.user. It is always an AnonymousUser. I can, however, retrieve the user id from the session and can confirm that the session cookie is being set correctly.

What am I missing?

I do not want to use a relational db as I want to maintain all my user data in couchdb.

Edit: I have written a class which does not inherit from Django's auth User. It, however, has the username and email attributes. For this reason, my backend does not return a class which derives from auth User.

like image 808
SharePoint Newbie Avatar asked Mar 21 '11 11:03

SharePoint Newbie


2 Answers

The request.user is set by the django.contrib.auth.middleware.AuthenticationMiddleware.

Check django/contrib/auth/middleware.py:

class LazyUser(object):     def __get__(self, request, obj_type=None):         if not hasattr(request, '_cached_user'):             from django.contrib.auth import get_user             request._cached_user = get_user(request)         return request._cached_user  class AuthenticationMiddleware(object):     def process_request(self, request):         request.__class__.user = LazyUser()         return None 

Then look at the get_user function in django/contrib/auth/__init__.py:

def get_user(request):     from django.contrib.auth.models import AnonymousUser     try:         user_id = request.session[SESSION_KEY]         backend_path = request.session[BACKEND_SESSION_KEY]         backend = load_backend(backend_path)         user = backend.get_user(user_id) or AnonymousUser()     except KeyError:         user = AnonymousUser()     return user 

Your backend will need to implement the get_user function.

like image 132
dgel Avatar answered Sep 17 '22 18:09

dgel


I too have custom authentication backend and always got AnonymousUser after successful authentication and login. I had the get_user method in my backend. What I was missing was that get_user must get the user by pk only, not by email or whatever your credentials in authenticate are:

class AccountAuthBackend(object):  @staticmethod def authenticate(email=None, password=None):     try:         user = User.objects.get(email=email)         if user.check_password(password):             return user     except User.DoesNotExist:         return None  @staticmethod def get_user(id_):     try:         return User.objects.get(pk=id_) # <-- tried to get by email here     except User.DoesNotExist:         return None 

Its easy to miss this line in the docs:

The get_user method takes a user_id – which could be a username, database ID or whatever, but has to be the primary key of your User object – and returns a User object.

It so happened that email is not primary key in my schema. Hope this saves somebody some time.

like image 27
yentsun Avatar answered Sep 21 '22 18:09

yentsun