Search code examples
pythondjangodjango-authenticationdjango-users

Django user authentication with case insensitive username


I'm completing my first project in Django, I'm still struggling when I need to find documentation about the problem that I cannot manage to solve, then I thought to post a question here. In my django project I installed the app "users" for the authentication, I have the following views.py in the folder "users":

from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.contrib.auth.forms import UserCreationForm


    def register(request):
        """Register a new user:"""
        if request.method != 'POST':
            # Display blank reigistration form.
            form = UserCreationForm()
        else:
            # Process completed form.
            form = UserCreationForm(data=request.POST)
            
            if form.is_valid():
                new_user = form.save()
                # Log the user in and then redirect to home page.
                login(request, new_user)
                return redirect('learning_journals:index')
    
    
        # Display a blank or invalid form
        context = {'form':form}
        return render(request, 'registration/register.html', context)

Models.py is empty at the moment. Everything is perfect and everything works well, both the form and the backend. Users can access with no problem.

When a user signs in, is obliged to use a case sensitive username. I would like the user to be able to log in with a case insensitive username, but I have no idea how to start and make this possible.

Thank you very much in advance for your help. Please let me know if you would like more info about my project.

python -m django --version ---> 3.2.9

Bye!


Solution

  • You should make a custom authentication backend, you can do this with:

    # app_name/backends.py
    
    from django.contrib.auth import get_user_model
    from django.contrib.auth.backends import ModelBackend
    
    UserModel = get_user_model()
    
    class CaseInsensitiveModelBackend(ModelBackend):
        
        def authenticate(self, request, username=None, password=None, **kwargs):
            if username is None:
                username = kwargs.get(UserModel.USERNAME_FIELD)
            if username is None or password is None:
                return
            try:
                user = UserModel._default_manager.get(username__iexact=username)
            except UserModel.DoesNotExist:
                UserModel().set_password(password)
                return
            if user.check_password(password) and self.user_can_authenticate(user):
                return user

    then you specify the AUTHENTICATION_BACKENDS setting [Django-doc] as:

    # settings.py
    
    # …
    
    AUTHENTICATION_BACKENDS = ['app_name.backends.CaseInsensitiveModelBackend']
    
    # …