Django authenticate() always returns None

I am building a web project with Django to facilitate distribution in case of an earthquake. The user needs to be a member as a Mukhtar or a Helper. The registration system works successfully. But the login part is constantly returning None value even though my login information is absolutely correct.

models.py:

from django.db import models
from django.contrib.auth.models import AbstractUser
from base64 import b32encode
from hashlib import sha1
from random import random

# Create random id
def pkgen():
    rude = ('lol',)
    bad_pk = True
    while bad_pk:
        pk = b32encode(sha1(str(random())).digest()).lower()[:24]
        bad_pk = False
        for rw in rude:
            if pk.find(rw) >= 0: bad_pk = True
    return pk

# Create your models here.
class User(AbstractUser):
    muhtar = models.BooleanField(null=False,default=False)
    tc = models.CharField(max_length=11, null=False, unique=True)
    address = models.TextField(null=False)
    need_help = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'tc' #Uyarı! Bu benzersiz olmasını ister
    REQUIRED_FIELDS = ['username']
    def __str__(self):
        return f"{self.username}"

class sos(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    sos_key = models.CharField(max_length=24, primary_key=True, default=pkgen, unique=True)
    address = models.TextField(null=False, unique=False)
    
    def __str__(self):
        return f"{self.user}"

views.py:

from django.shortcuts import render, redirect
from .models import User
from django.contrib.auth import authenticate, login, logout

# Create your views here.
def index(request):
    return render(request, "harita.html")

def register(request):
    if request.method == "POST":
        username = request.POST.get("kullaniciadi")
        email = request.POST.get("email")
        tc = request.POST.get("tc-no")
        password = request.POST.get("password")
        muhtar = request.POST.get("muhtar-check")
        if muhtar == "on":
            muhtar = True
        else:
            muhtar = False
        if username == "" or password == "" or tc == "" or email == "":
            return render(request, "register.html", {"error": "LĂŒtfen tĂŒm alanları doldurun."})
        #elif len(tc) != 11:
        #    return render(request, "register.html", {"error": "TC kimlik numarası 11 haneli olmalıdır."})
        elif User.objects.filter(tc=tc).exists() or User.objects.filter(email=email).exists():
            return render(request, "register.html", {"error": "Bu kimlik numarası veya e-posta adresi zaten kullanılıyor."})
        else:
            user=User.objects.create_user(username=username, email=email, password=password, tc=tc, muhtar=muhtar)
            user.save()
            return redirect("login")
    return render(request, "register.html")

def login(request):
    if request.method == "POST":
        tc = request.POST.get("tc-no")
        password = request.POST.get("password")
        email = request.POST.get("email")
        if tc == "" or password == "" or email == "":
            return render(request, "login.html", {"error": "LĂŒtfen tĂŒm alanları doldurun."})
        user = authenticate(request=request, tc=tc, password=password, email=email)
        print(user)
        if user is not None:
            login(request, user)
            return redirect("index")
        else:
            print(f"""
***************
TC: {tc}
ƞifre: {password}
E-posta: {email}
***************""")
            return render(request, "login.html", {"error": "E-posta, T.C. veya Ɵifre hatalı."})
    return render(request, "login.html")

def logoutPage(request):
    logout(request)
    return render(request, 'logout.html')

def profile(request):
    if request.user.is_authenticated == False:
        return redirect("register")
    else:
        user = User.objects.get(tc=request.user.tc)
        return render(request, "profile.html", {"user": user})

def sos(request):
    if request.user.is_authenticated == False:
        return redirect("register")
    elif not request.user.muhtar:
        return render(request, "harita.html", {"error": "Yardım çağırma yetkiniz yok."})

    if request.method == "POST":
        malzemeler = request.POST.get("exampleFormControlTextarea1")
        
        if not malzemeler:
            return render(request, "sos.html", {"fillError": "LĂŒtfen gerekli alanları doldurun."})
        
        # Kullanıcının adresini ve usernamesini alabilirsiniz, örneğin:
        adres = request.user.address
        username = request.user.username
        
        # İƟlemlerinizi yapabilirsiniz, örneğin bu bilgileri bir veritabanına kaydedebilirsiniz.
        
        # BaƟarılı bir Ɵekilde iƟlem yapıldığında kullanıcıya bir mesaj göndermek için
        return render(request, "sos.html", {"succmsg": "Yardım çağrınız baƟarıyla gönderildi."})
    
    return render(request, "sos.html")

login.html:

{% load static %}
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GiriƟ Sayfası</title>
    <link rel="stylesheet" href="{% static 'libs/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'register_and_login.css' %}">
    <script src="{% static 'libs/jquery.min.js' %}"></script>
</head>

<body>
    {% block navbar %}
        {% include "navbar.html" %}
    {% endblock navbar %}
    <div class="container">
        <br>
        <div id="brs">
            <br><br><br><br>
        </div>
        <!--giriƟ formu-->
        <form id="giris-form" method="POST">
            {% csrf_token %}
            {% if error %}
                <div class="alert alert-danger">{{ error }}</div>
            {% endif %}
            <h3>GiriƟ Yap</h3>

            <label for="email">Email</label>
            <input type="text" id="email" name="email">

            <label for="tc-no">T.C. kimlik numarası</label>
            <input type="text" id="tc-no" name="tc-no">

            <label for="parola">Parola</label>
            <input type="password" id="parola" name="password">

            <button type="submit" id="giris-yap">GiriƟ Yap</button>
        </form>
    </div>
</body>

</html>

I’m in a really difficult situation. I need to finish the project urgently and I can’t make any progress because of this problem.

There are several errors in your code:

  • your user model declares ‘username’ as a required field whereas the model does not have such field. self.username used in the __str__ method is likely to fail because this field does not exist.

  • I suppose you use django.contrib.auth.backends.ModelBackend as authentication backend in your settings. If so, the parameters passed to authenticate method should be username and password (not tc and password) : this is the backend which will map the username parameter with the tc field of yhe model based on USERNAME_FIELD value. Changing tc=tc to username=tc in the call to authenticate should solve your issue

1 Like

the first point of view is that the function to register user is very extensive and can be improved in a more optimal way and the second point of view that I observe is in your html, since in the form tag you only have the id and method==“POST” but the action==" corresponding endpoint" is missing since that is the one that points to the endpoint of your url. I would like to see your urls to see if they are correct and also the error that you comment.

1 Like

Do you know what is the error I have been dealing with for 5 days? On the HTML registration page, I saved the name tag as “parola”, but this is Turkish, but I translated that word into English in request.POST.get(). Since there is no such tag, it returns an empty value. Django encrypts it and saves it to the database. When I enter the real password on the login page, the empty value does not match the hash value and the authenticate function returns None. Dude, I’m an idiot and I’ve been dealing with this for 5 days. I almost quit my software career :D. Thanks!

i am creating django application but while login i am getting null in authentication I am adding my code
model.py

class CustomUserManager(BaseUserManager):
def create_user(self, email, name, password=None, role=‘user’):
if not email:
raise ValueError(‘Users must have an email address’)
if not name:
raise ValueError(‘Users must have a name’)

    user = self.model(
        email=self.normalize_email(email),
        name=name,
        role=role,
    )

    user.set_password(password)
    user.save(using=self._db)
    return user

def create_superuser(self, email, name, password):
    user = self.create_user(
        email=self.normalize_email(email),
        name=name,
        password=password,
        role='admin',  # Set the role to 'admin' for superuser
    )
    user.is_admin = True
    user.is_staff = True
    user.save(using=self._db)
    return user

class CustomUser(AbstractBaseUser):
email = models.EmailField(verbose_name=‘email address’, max_length=255, unique=True)
name = models.CharField(max_length=255)
address = models.CharField(max_length=255)
country = models.CharField(max_length=255)
qualifications = models.TextField(blank=True)
skills = models.TextField(blank=True)
exprence = models.IntegerField(max_length=255)
exp_details = models.CharField(max_length=255)
role = models.CharField(max_length=50, default=‘user’) # Add the ‘role’ field
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)

objects = CustomUserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']

def __str__(self):
    return self.email

def has_perm(self, perm, obj=None):
    return self.is_admin

def has_module_perms(self, app_label):
    return True

forms.py

class SignUpForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
confirm_password = forms.CharField(widget=forms.PasswordInput)
qualifications = forms.CharField(widget=forms.TextInput(attrs={‘placeholder’: ‘Enter qualifications as comma-separated values’}), required=False)
skills = forms.CharField(widget=forms.TextInput(attrs={‘placeholder’: ‘Enter skills as comma-separated values’}), required=False)

class Meta:
    model = CustomUser
    fields = ['email', 'name', 'address', 'country', 'qualifications', 'skills', 'exprence', 'exp_details', 'password', 'confirm_password']

def clean_confirm_password(self):
    password = self.cleaned_data.get('password')
    confirm_password = self.cleaned_data.get('confirm_password')
    if password != confirm_password:
        raise forms.ValidationError("Passwords do not match")
    return confirm_password

def clean_experience(self):
    experience = self.cleaned_data.get('qualifications')
    return experience.split(',') if experience else []

def clean_skills(self):
    skills = self.cleaned_data.get('skills')
    return skills.split(',') if skills else []

def save(self, commit=True):
    user = super(SignUpForm, self).save(commit=False)
    user.set_password(self.cleaned_data["password"])
     # Check if qualifications is a string before splitting
    qualifications = self.cleaned_data["qualifications"]
    if isinstance(qualifications, str):
        user.qualifications = qualifications.split(",")  # Convert experience to a list
    else:
        user.qualifications = qualifications  # Use the existing list

# Check if skills is a string before splitting
    skills = self.cleaned_data["skills"]
    if isinstance(skills, str):
        user.skills = skills.split(",")  # Convert skills to a list
    else:
        user.skills = skills  # Use the existing list  # Convert skills to a list
    if commit:
        user.save()
    return user

class EmailAuthenticationForm(AuthenticationForm):
username = forms.EmailField(label=‘Email’)

class LoginForm(forms.Form):
email = forms.EmailField(label=‘Email’)
password = forms.CharField(label=‘Password’, widget=forms.PasswordInput)

views.py

def signup(request):
if request.method == ‘POST’:
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
return redirect(‘login’) # Redirect to login page after successful signup
else:
form = SignUpForm()
return render(request, ‘signup.html’, {‘form’: form})

from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from .forms import LoginForm
from django.contrib import messages

def custom_login(request):
error_message = None
if request.method == ‘POST’:
form = LoginForm(request.POST)
if form.is_valid():
email = form.cleaned_data[‘email’]
password = form.cleaned_data[‘password’]
print(f"Email: {email}, Password: {password}") # Debug statement

        # Authenticate the user
        user = authenticate(request, username=email, password=password)
        print(f"Authenticated User: {user}")  # Debug statement

        if user is not None:
            # Login the user
            login(request, user)
            messages.success(request, 'Login successful.')

            # Redirect to the home page
            return redirect('home')

        else:
            error_message = 'Invalid email or password.'
    else:
        error_message = 'Form is not valid.'
else:
    form = LoginForm()

return render(request, 'login.html', {'form': form, 'error_message': error_message})

Welcome @Gaurav-Sarswat !

I suggest you open a new topic for your issue here rather than trying to add to this one.
Also note: When posting code here, enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted.

Hi @KenWhitesell
I Have created a new topic Always getting None in authenticate()
Can you please help me?