Skip to content

Authentication

Django's django.contrib.auth provides a complete authentication framework. It handles user verification, passwords, and custom backends.

The User Object

The default model django.contrib.auth.models.User tracks users.

  • Fields: username (required, unique), password (hashed), email, first_name, last_name, is_active, is_staff, is_superuser, last_login, date_joined.
  • Creation: Always use User.objects.create_user(username, email, password) to ensure passwords are hashed. For superusers, use python manage.py createsuperuser.
  • Custom Model: Substitute your own user model before the first migration. See Custom User Model.

Logging In & Out

Use authenticate() to verify credentials and login() to attach the user to the session. logout() clears the session.

python
from django.contrib.auth import authenticate, login, logout

def my_login(request):
    user = authenticate(request, username="...", password="...")
    if user is not None:
        login(request, user)
        
def my_logout(request):
    logout(request)
python
from django.contrib.auth import aauthenticate, alogin

async def async_login(request):
    user = await aauthenticate(request, username="...", password="...")
    if user: 
        await alogin(request, user)

Protecting Views

Restrict access using decorators or mixins. Unauthenticated users are redirected to LOGIN_URL.

python
from django.contrib.auth.decorators import login_required, login_not_required

@login_required
def dashboard(request):
    ...
python
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import View

class DashboardView(LoginRequiredMixin, View):
    ...

TIP

Use LoginRequiredMiddleware to require login site-wide, and @login_not_required for specific public pages.

Built-in Authentication Views

Django provides class-based views for common flows (login, logout, password change/reset) in django.contrib.auth.views. Include them in your URLconf:

python
path("accounts/", include("django.contrib.auth.urls")),

This registers URLs like login, logout, password_change, and password_reset. You only need to provide templates in a registration/ folder (e.g., registration/login.html).

Password Management

Django stores passwords as secure hashes, never plain text.

  • Hashing: Use user.set_password("new") and user.check_password("new"). For standalone hashing, use make_password() and check_password().
  • Hashers (PASSWORD_HASHERS): Django uses PBKDF2 by default, but Argon2 is recommended (python -m pip install "django[argon2]").
  • Validation (AUTH_PASSWORD_VALIDATORS): Enforce password strength (e.g., minimum length, blocklisting common passwords).
  • Passwordless Accounts: Use user.set_unusable_password() for accounts authenticated via external SSO to prevent local login attempts.

Custom Authentication Backends

When credentials live elsewhere (LDAP, SSO), define a custom backend by subclassing BaseBackend or ModelBackend.

python
from django.contrib.auth.backends import ModelBackend

class EmailBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        # Implement custom lookup/verification (e.g., by email)
        pass

Register it in settings:

python
AUTHENTICATION_BACKENDS = [
    "myapp.backends.EmailBackend",
    "django.contrib.auth.backends.ModelBackend", # Keep default as fallback
]

Backends are checked in order. If authenticate() returns a user, they are logged in. If a backend raises PermissionDenied, the entire login process fails immediately.