1
votes

I am trying custom authentication with django, I wrote a class and filled it with the methods authenticate and get_user, I also added this authentication to the AUTHENTICATION_BACKENDS in settings.py file.

I have called authenticate method and followed it up with login in my view.

Everything seems to work fine,

  1. is_authenticated returns true for the user after login,
  2. user.backends set to my custom backend.
  3. sessionid cookie is getting set in my browser

But the subsequent requests have request.user as anonymous, unable to figure out the reason, require your help. Sharing the code below, I am just trying it to learn custom authentication.

views.py

 def home(request):
   if not request.user.is_authenticated():
    user=authenticate(username=None,passwd=None,request=request)
    if not user:
        return HttpResponse("Login Failed")
    else:
        login(request,user)
        return HttpResponse("Logged in Successfully")

cusauth.py

class CustomloginBackend:

  def authenticate(self,username=None,passwd=None,request=None):
    return self.get_user("praveen.madhavan")

  def get_user(self,username):
    try:
        return User.objects.get(username=username)
    except Exception as e:
        return False

What could be the problem ?

Thanks

Praveen.M

3
Did you find a fix for this? - Benjamin

3 Answers

1
votes

The Question is pretty old and maybe you found the answer but the reason why a user is not logged in for the subsequent requests is that the authenticate method does not save the authenticated user in session for that you need to use login method after authentication from the same module.

From docs:

def authenticate(request=None, **credentials):
    """
    If the given credentials are valid, return a User object.
    """

def login(request, user, backend=None):
    """
    Persist a user id and a backend in the request. This way a user doesn't
    have to reauthenticate on every request. Note that data set during
    the anonymous session is retained when the user logs in.
    """

[source]

https://docs.djangoproject.com/en/2.1/_modules/django/contrib/auth/#authenticate

[docs]

https://docs.djangoproject.com/en/2.1/topics/auth/default/#django.contrib.auth.authenticate

https://docs.djangoproject.com/en/2.1/topics/auth/default/#django.contrib.auth.login

1
votes

Is "username" field the primary key of your user model? The get_user function should take the primary key of user model as Django document said.

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 or None.

So in your case, simply change the keyword parameter of User.objects.get if username is the PK of your model.

def get_user(self,username):
    try:
        return User.objects.get(pk=username)
    except Exception as e:
        return None

Or if username is not the PK, then try this:

def get_user(self,user_id):
    try:
        return User.objects.get(pk=user_id)
    except Exception as e:
        return None
0
votes

Django uses following (from django.contrib.auth.__init__) to get logged-in user and pass it to AuthenticationMiddleware to set request.user

SESSION_KEY = '_auth_user_id'
BACKEND_SESSION_KEY = '_auth_user_backend'

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

Probably, you are passing the wrong value to backend.get_user so it fails to retrieve the correct user so ıit sets AnonymousUser to request. You may try to debug to see if backend.get_user works as you expected