BudiBadu Logo
Samplebadu

Django by Example: User Authentication

Django 5.0+

How to manually log a user in and out. While Django provides built-in views for this, this code example shows how understanding the underlying authenticate() and login() functions is essential for custom flows.

Code

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

def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        
        # 1. Authenticate
        # Checks credentials against the database
        # Returns a User object if valid, None otherwise
        user = authenticate(request, username=username, password=password)
        
        if user is not None:
            # 2. Login
            # Creates the session and attaches user to request
            login(request, user)
            
            messages.success(request, "Welcome back!")
            return redirect('home')
        else:
            messages.error(request, "Invalid username or password.")
            
    return render(request, 'login.html')

def logout_view(request):
    # 3. Logout
    # Clears the session data
    logout(request)
    return redirect('login')

Explanation

Django's authentication system decouples credential verification from session creation. The authenticate() function is the gateway; it accepts credentials (usually username and password) and iterates through the configured AUTHENTICATION_BACKENDS to verify them. If valid, it returns a User object; otherwise, it returns None. This design allows you to easily swap or stack backends (e.g., LDAP, OAuth, or custom logic) without changing your view code.

Once authenticated, the login() function establishes a session for the user. It creates a session record in the database and sets a cookie in the browser. Crucially, login() also rotates the session ID to prevent "session fixation" attacks, ensuring that a stolen pre-login session ID cannot be used to hijack the authenticated session.

The logout() function flushes the session data and removes the session cookie. It is best practice to redirect the user immediately after logout to prevent browser caching issues from showing sensitive data on the "back" button.

Code Breakdown

13
authenticate(request, ...). Always pass request as the first argument (required by some custom auth backends). This function is secure; it doesn't log anything in if it fails, it just returns None.
18
login(request, user). This sets request.session['_auth_user_id']. After this line, request.user will be the logged-in user on all subsequent requests.
30
logout(request). Flushes the session. It's good practice to redirect the user immediately after calling this.
20
messages.success. A common pattern is to provide feedback after auth actions. These messages persist for one request (via the session) so they appear on the redirected page.