0

I am working on a django authentication project, where I want to authenticate using both email and username for authentication. The model is

class LinksUser(AbstractBaseUser, PermissionsMixin):
    objects = LinksUserManager()
    full_name = models.CharField(max_length=200, blank=False)
    email = models.EmailField(_("email address"), unique=True)
    username = models.CharField(_("username"), unique=True, max_length=20)
    is_active = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)

    USERNAME_FIELD = "username"
    EMAIL_FIELD = "email"
    REQUIRED_FIELDS = ['email']

    def __str__(self):
        return self.email

In addition I have created a manager file which is

class LinksUserManager(BaseUserManager):
    """
    Custom user-model manager where the email and username are identifiers
    for authentication
    """

    def create_user(self, email, username, password, **extra_fields):
        if not username:
            raise ValueError('Username must be set')
        if not email:
            raise ValueError('Email must be set')
        email = self.normalize_email(email)
        user = self.model(username=username, email=email)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True.'))

        return self.create_user(username, email, password, **extra_fields)```


Finally, I wrote an authentication code of 


from .models import LinksUser

class LinkUserBackend(object): """ Model backend that attempts to allow a user to log in with either the username or the email address """

def authenticate(self, request, username=None, password=None):
    try:
        user = LinksUser.objects.get(email=username)
    except LinksUser.DoesNotExist:
        try:
            user = LinksUser.objects.get(username=username)
        except LinksUser.DoesNotExist:
            return None
    if user.check_password(password):
        return user
can anyone please tell me why my authentication procress may not be allowing me to login eventhough creating the superuser ask for everything that I told it to. 

1 Answers1

0
  • Here I write code for authenticating with (email or username)
  • Here the tricky part is I take (username and email) both are as required fields & used regex validation for email.

models.py

from django.db import models
from django.contrib.auth.models import (AbstractBaseUser, BaseUserManager, PermissionsMixin)
from django.utils.translation import gettext as _
# Create your models here.
class LinksUserManager(BaseUserManager):

    use_in_migrations = True

    def _create_user(self, username, email, password, **extra_fields):
        values = [email]
        field_value_map = dict(zip(self.model.REQUIRED_FIELDS, values))
        for field_name, value in field_value_map.items():
            if not value:
                raise ValueError("The {} value must be set".format(field_name))

        email = self.normalize_email(email)
        user = self.model(username=email,email=username, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        
        return user

    def create_user(self,username, email, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", False)
        extra_fields.setdefault("is_superuser", False)
        return self._create_user(email,username, password, **extra_fields)

    def create_superuser(self,username, email, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)

        if extra_fields.get("is_staff") is not True:
            raise ValueError("Superuser must have is_staff=True.")
        if extra_fields.get("is_superuser") is not True:
            raise ValueError("Superuser must have is_superuser=True.")

        return self._create_user(email,username, password, **extra_fields)


class LinksUser(AbstractBaseUser, PermissionsMixin):
    full_name = models.CharField(max_length=200, blank=False)
    email = models.EmailField( unique=True)
    username = models.CharField(unique=True, max_length=20)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    USERNAME_FIELD = "username"
    REQUIRED_FIELDS = ['email']

    objects = LinksUserManager()
    def __str__(self):
        return self.email

views.py

from django.shortcuts import render,redirect
from .form import UserLoginForm
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from .models import LinksUser
import re

regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' # email validation using regex 
def SigninView(request):
  form = UserLoginForm()
  if request.method == 'POST':
      email_or_uname = request.POST.get('email_or_uname')
      upass = request.POST.get('password')
      if re.fullmatch(regex, email_or_uname): # authenticate with email
        get_user = LinksUser.objects.filter(email=email_or_uname)
        if not len(get_user) == 0:
        
          user = authenticate(username=get_user[0].username,password=upass)
          if user is None:
              messages.error(request,'Please Enter Correct Credinatial')
              return redirect('/')
          else:
              login(request,user)
              messages.success(request,f'Login Successful with (email) - {user.email}')
          return redirect('/dash/')
        else:
          print('Invalid Credential !')
          return redirect('/')
      else:                             # authenticate with username  
        user = authenticate(username=email_or_uname,password=upass)
        print(user)
        if user is None:
            messages.error(request,'Please Enter Correct Credinatial')
            return redirect('/')
        else:
            login(request,user)
            messages.success(request,f'Login Successful (username) - {user.username}')
        return redirect('/dash/')
  else:
      if request.user.is_authenticated:
          return redirect('/dash/')
      else:
          return render(request,'index.html',{'form':form})

Browser Output

enter image description here