pythondjangodjango-authenticationdjango-usersdjango-auth-models

how do i set my authentication backend as default in settings.py file of my django project(Extended AbstractBaseUser model)


I have written the following class for Auth Back end and placed it inside a file "authentication.py" inside the app directory:

from events.models import User

class authBackend():
    def authenticate(self, request, username, passwprd):
        try:
            user = User.objects.get(rollNo=username)
            success = user.check_password(password)
            if success:
                return user
        except User.DoesNotExist:
            pass
        return None

    def get_user(self, uid):
        try:
            return User.objects.get(pk=Uid)
        except:
            return None

then i added (or at least i thought i did) it to settings.py:

AUTHENTICATION_BACKENDS = [
    'events.authentication'
]

this is how i am logging in the user:

def login_view(request):
    if request.method == "POST":

        # Attempt to sign user in
        rollno = request.POST["rollno"]
        password = request.POST["password"]

        user = authenticate(request, username=rollno, password=password)

        # Check if authentication successful
        if user is not None:
            login(request, user)
            return HttpResponseRedirect(reverse("events:index"))
        else:
            return render(request, "events/login.html", {
                "message": "Invalid roll number and/or password."
            })
    else:
        return render(request, "events/login.html")

But i am getting the following trace back:

ImportError at /login Module "events" does not define a "authentication" attribute/class

I am a noob and i am pretty sure i am doing something wrong, i just don't understand what it is.

Can someone please tell me how to do it right?


Solution

  • You need to import it with the class name as well, so:

    AUTHENTICATION_BACKENDS = [
        'events.authentication.authBackend'
    ]

    In your authBackend, you also made a number of mistakes. First of all the authentication backend needs to implement a number of functions [Django-doc]:

    The user model and its manager will delegate permission lookup functions (get_user_permissions(), get_group_permissions(), get_all_permissions(), has_perm(), has_module_perms(), and with_perm()) to any authentication backend that implements these functions.

    You thus will need to implement this functions as well. Therefore it might be better to inherit from the BaseBackend [Django-doc] or perhaps even better from the ModelBackend, since that will already implement the logic, and you thus only need to override certain functions to let it work with your new model.

    You also made a typo in the parameter names: it is password, not passwprd:

    from django.contrib.auth.backends import BaseBackend
    from events.models import User
    
    class authBackend(BaseBackend):
        def authenticate(self, request, username, password):
            try:
                user = User.objects.get(rollNo=username)
                success = user.check_password(password)
                if success:
                    return user
            except User.DoesNotExist:
                pass
            return None
    
        def get_user(self, uid):
            try:
                return User.objects.get(pk=Uid)
            except:
                return None

    Note: According to the PEP-8 Style guide [pep-0008], class names are written in PerlCase starting with an uppercase, so you might want to consider renaming authBackend to AuthBackend.