6

I am working on a Django project in which I have defined a custom user model for which I have required to write the custom authentication method, by following the documentation I have written it like following But I have a problem in calling it in the views.py kindly help me by looking in the following code
I have defined my custom backend as follows
My Custom Authentication Backend

from django.contrib.auth.backends import BaseBackend
from .models import User
from IntellerMatrix.CommonUtilities.constants import Constants


class AuthenticationBackend(BaseBackend):
    """
    Authentication Backend
    :To manage the authentication process of user
    """

    def authenticate(self, email=None, password=None):
        user = User.objects.get(email=email)
        if user is not None and user.check_password(password):
            if user.is_active == Constants.YES:
                return user
            else:
                return "User is not activated"
        else:
            return None

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

settings.py

AUTHENTICATION_BACKENDS = ['Modules.users.authentication.AuthenticationBackend',
                           'django.contrib.auth.backends.ModelBackend', ]

Views.py

def login(request):
    email = 'ialihaider75@gmail.com'
    password = 'ali'
    user = # how to call here that custom authentication backend's authenticate method

    if user is None:
        return HttpResponse("<p>Not Valid</p>")
    else:
        return HttpResponse(user)
RIO
  • 148
  • 1
  • 8

2 Answers2

3

You can call the authenticate(..) function [Django-doc]

Use authenticate() to verify a set of credentials. It takes credentials as keyword arguments, username and password for the default case, checks them against each authentication backend, and returns a User object if the credentials are valid for a backend. So:

from django.contrib.auth import authenticate

def login(request):
    email = 'ialihaider75@gmail.com'
    password = 'ali'
    user = authenticate(request, email=email, password=password)

    if user is None:
        return HttpResponse('<p>Not Valid</p>')
    else:
        return HttpResponse(user)

Note that the authentication method you implement can not return a string. As the documentation on writing an authentication backend says:

(…)

Either way, authenticate() should check the credentials it gets and return a user object that matches those credentials if the credentials are valid. If they’re not valid, it should return None.

class AuthenticationBackend(BaseBackend):
    """
    Authentication Backend
    :To manage the authentication process of user
    """

    def authenticate(self, request, email=None, password=None):
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return None
        if user is not None and user.check_password(password):
            if user.is_active == Constants.YES:
                return user
        return None

Furthermore this does not logs in your use, this simply checks if the credentials are valid. So you still need to call the login(..) function [Django-doc] if you want to log in the user.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • authenticate() method comes from which library I mean I have to import what to call authenticate() as you mention above. – RIO Feb 08 '20 at 12:44
  • @IPFlashorAli: as specified on the top line: `from django.contrib.auth import authenticate ` – Willem Van Onsem Feb 08 '20 at 12:47
  • ok, I have called it but my authentication method getting failed. – RIO Feb 08 '20 at 12:49
  • I think my custom method is not calling instead Django always calls its default authenticate() method – RIO Feb 08 '20 at 12:51
  • @IPFlashorAli: as the documentation specifies: it will iterate over the backends and call these. You however forgot to add the `request` parameter, so that might be a reason why it fails. I advise to carefully read the documentation, and respect the conditions, otherwise it will indeed likely not work. Note that you need to pass the parameters (`email` and `password`) as *named* parameters. – Willem Van Onsem Feb 08 '20 at 12:51
  • Well, thanks for the kind advice I have done everything the same as you mentioned bro, and from the list of AUTHENTICATION_BACKENDS I also have remove the django.contrin.auth.ModelBackEnd to confirm that is my backend getting called or not but I think it's not working actually I also want to check some parameters from DB for authentication that is why I have written mine one. But I think its not working like this – RIO Feb 08 '20 at 12:56
2

Instead of calling authenticate() method of your Backend class directly you'd better use authenticate() function:

user = authenticate(email=email, password=password)

This is more general and make your code flexible. Since you may have different auth backend which accept different argument e.g. token. So instead of import all backends and try each of them you can just pass required arguments to authenticate function and this will automaticaly call every auth backend.

neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100