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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With