Working with Django's Authentication System

Initializing a Superuser

Execute the following management command to create an administrative account:

python manage.py createsuperuser

During the prompt:

  • Username: Required.
  • Email: Optional.
  • Password: Will be stored as a hash. If forgotten, you can manually replace the hash in the database, though resetting via management commands is preferred.

Verifying Credentials

Use authenticate to validate a user's identity against the database.

from django.contrib.auth import authenticate

validated_user = authenticate(request, username=input_username, password=input_password)
if validated_user:
    # Credentials are correct
    pass

Supporting Multiple Login Identifiers

To allow users to log in using either a username or an email address, implement a custom authentication backend.

from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from .models import UserProfile

class DualIdentifierBackend(ModelBackend):
    """Authenticates users via username or email."""

    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            target_user = UserProfile.objects.filter(
                Q(username=username) | Q(email=username)
            ).first()
            
            if target_user and target_user.check_password(password):
                return target_user
        except UserProfile.DoesNotExist:
            return None

Register this backend in your settings.py:

AUTHENTICATION_BACKENDS = ['myapp.backends.DualIdentifierBackend']

Session Management

Logging In

The login function attaches session data to request for a verified user.

from django.contrib.auth import authenticate, login

def handle_login(request):
    user_id = request.POST.get('user_id')
    secret = request.POST.get('secret')
    account = authenticate(username=user_id, password=secret)
    
    if account:
        login(request, account)
        # Proceed to dashboard
    else:
        # Display error message

Logging Out

Terminate the user session using the logout helper.

from django.contrib.auth import logout

def handle_logout(request):
    logout(request)
    # Session cleared

Working with User Instances

The default User model includes username and password. The password is stored using a secure hash.

  • is_staff: Grants access to the admin interface.
  • is_active: Controls login ability. Setting this to False disables the account without deleting it.

Checking Authentication Status

Use is_authenticated to verify if the current request belongs to a logged-in user. This does not check permissions or active status.

if request.user.is_authenticated:
    # User is logged in, display request.user.username

Implementation Scenario: Restrict views to authenticated users only.

Option 1: Manual Check

def protected_view(request):
    if not request.user.is_authenticated:
        return redirect(f'{settings.LOGIN_URL}?next={request.path}')
    # View logic here

Option 2: Decorator

Use the @login_required decorator for cleaner code.

from django.contrib.auth.decorators import login_required

@login_required
def protected_view(request):
    # View logic here

User Management

Creating Accounts

Create standard users:

from django.contrib.auth.models import User

new_account = User.objects.create_user(
    username='john_doe', 
    password='s3cr3t', 
    email='john@example.com'
)

Create superusers:

super_account = User.objects.create_superuser(
    username='admin', 
    password='admin_pass', 
    email='admin@example.com'
)

Password Handling

Verification: Check if a plaintext password matches the stored hash.

if request.user.check_password('candidate_password'):
    # Password matches

Updating: Never set the password attribute directly; use the hasher.

from django.contrib.auth import hashers

account = User.objects.get(username='john_doe')
account.password = hashers.make_password('new_secure_password')
account.save()

Password Change Example:

from django.contrib.auth import hashers
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render

@login_required
def change_password(request):
    error = ""
    if request.method == 'POST':
        current = request.POST.get('current_pwd')
        pwd1 = request.POST.get('new_pwd')
        pwd2 = request.POST.get('confirm_pwd')
        
        if not request.user.check_password(current):
            error = "Incorrect current password."
        elif pwd1 != pwd2:
            error = "New passwords do not match."
        elif not pwd1:
            error = "New password cannot be empty."
        else:
            request.user.password = hashers.make_password(pwd1)
            request.user.save()
            return redirect('/login/')
            
    return render(request, 'change_pwd.html', {'error': error})

Extending the User Model

If the default auth_user table lacks required fields (e.g., a phone number), do not create a separate table. Instead, extend the AbstractUser class.

from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    user_id = models.AutoField(primary_key=True)
    mobile = models.CharField(max_length=11, unique=True, null=True)

    def __str__(self):
        return self.username

Crucial Step: Inform Django to use your custom model in settings.py:

AUTH_USER_MODEL = 'myapp.CustomUser'

Password Hashing Mechanics

Django generates unique hashes even for identical passwords using a combination of algorithm, iterations, a salt, and the hash:

pbkdf2_sha256$  # Algorithm
260000$         # Iterations
SALT_STRING$    # Random salt
HASHED_VALUE$   # Resulting hash

To hash a password manually:

from django.contrib.auth.hashers import make_password
hash_result = make_password('password123')

To verify:

from django.contrib.auth.hashers import check_password
is_valid = check_password('password123', hash_result)

Tags: Django Authentication python Web Security Backend Development

Posted on Tue, 02 Jun 2026 16:24:57 +0000 by Negligence