0

I am trying to write a custom UserModel and Email Authentication backend. When I tried to override authenticate method. user=UserModel.objects.get(email=email) returned none.

Here are my models.py , authenticate.py, views.py,settings.py

models.py 

from django.db import models
from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin,BaseUserManager
from django.utils import timezone
# Create your models here.

class CustomUserManager(BaseUserManager):

    def _create_user(self,firstname,lastname,email,password,**extra):
        if not email:
            raise ValueError('You have not provided a valid email')
        
        email=self.normalize_email(email)
        if not firstname and not extra['is_superuser']:
            raise ValueError('You must have a first name')
        if not lastname and not extra['is_superuser']:
            raise ValueError('You must have a last name')
        
        user=self.model(
            email=email,
            firstname=firstname,
            lastname=lastname,
            **extra
        )
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_user(self,firstname=None,lastname=None,email=None,password=None,**extra):
        extra.setdefault('is_staff',False)
        extra.setdefault('is_superuser',False)
        extra.setdefault('is_active',True)
        return self._create_user(firstname,lastname,email,password,**extra)
    
    def create_superuser(self,firstname='admin',lastname='',email=None,password=None,**extra):
        extra.setdefault('is_staff',True)
        extra.setdefault('is_superuser',True)
        extra.setdefault('is_active',True)
        return self._create_user(firstname,lastname,email,password,**extra)


class UserModel(AbstractBaseUser,PermissionsMixin):
    firstname=models.CharField(max_length=100,default='')
    lastname=models.CharField(max_length=100,default='')
    email=models.EmailField(unique=True,default='',null=False,blank=False)
    is_active=models.BooleanField(default=True)
    is_superuser=models.BooleanField(default=False)
    is_staff=models.BooleanField(default=False)
    date_joined=models.DateTimeField(default=timezone.now)
    last_login=models.DateTimeField(blank=True,null=True)

    objects=CustomUserManager()
    USERNAME_FIELD='email'
    EMAIL_FIELD='email'
    REQUIRED_FIELDS=[]

    class Meta():
        verbose_name='UserModel'
        verbose_name_plural='UserModel'

    def get_full_name(self):
        return self.firstname + self.lastname








class Profile(models.Model):
    firstname=models.CharField(max_length=100,null=False,default='')
    lastname=models.CharField(max_length=100,null=False,default='')
    email=models.EmailField(null=False,unique=True)
    mobile=models.BigIntegerField()
    about=models.TextField(max_length=400)
    verified=models.BooleanField(verbose_name='verified',default=False)

    def __str__(self):
        return self.username
    



    
Authenticate.py

from django.contrib.auth.backends import BaseBackend
from django.contrib.auth import get_user_model


class EmailAuthBackend(BaseBackend):
    def authenticate(self, response, email=None, password=None, **kwargs):
        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(email=email)
        except UserModel.DoesNotExist:
            return None
        
        if user.check_password(password):
            return user
        else:
            return None

    
    def get_user(self,user_id):
        try:
            return get_user_model().objects.get(pk=user_id)
        except get_user_model().DoesNotExist:
            return None
    
Views.py
from django.shortcuts import render,redirect
from .models import *
from .authentication import EmailAuthBackend
from django.contrib.auth import logout,login
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
# Create your views here.

def Login(response):
    if response.method=='POST':
        email=response.POST.get('email')
        password=response.POST.get('password')
        user=EmailAuthBackend.authenticate(email,password)
        print(user)
        if user is not None:
            if user.is_active:
                login(response,user)
                return redirect('verify')
            else:
                return HttpResponse('User is not active')
        else:
            return redirect('login')
        
        
    return render(response, "users/screens/login.html", {})



def sign_up(response):
    if response.method=='POST':
        firstname=response.POST.get('firstname')
        lastname=response.POST.get('lastname')
        email=response.POST.get('email')
        password=response.POST.get('password')
        
        if UserModel.objects.filter(email=email).exists():
            return HttpResponse('User with this email already exist')
        else:
            UserModel.objects.create(
                firstname=firstname,
                lastname=lastname,
                email=email,
                password=password,
                )
            return redirect('login')
    return render(response, "users/screens/signup.html", {})

def forgot_password(response):
    return render(response, "users/screens/forgot_password.html", {})


def verify(response):
    return render(response, "users/screens/verify.html", {})
settings.py

#AUTHENTICATION BACKEND
AUTH_USER_MODEL='users.UserModel'
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'users.authentication.EmailAuthBackend',
]


I was expecting the user=UserModel.objects.get(email=email) to return the user object but I got none instead and the view redirected it to the login page itself.

1 Answers1

0

response is missing in login view:

user=EmailAuthBackend.authenticate(response, email, password)
Razenstein
  • 3,532
  • 2
  • 5
  • 17