Slide 1: Django Authentication System Overview
Django's authentication system is a robust framework that handles user accounts, groups, permissions, and cookie-based user sessions. It seamlessly integrates with Django's built-in views and forms, providing a secure foundation for user management in web applications.
# settings.py
INSTALLED_APPS = [
'django.contrib.auth', # Authentication framework
'django.contrib.contenttypes', # Required for auth
]
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
]
# Default authentication backends
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
]Slide 2: Basic User Model Implementation
Django provides a flexible User model that can be extended or customized. The default User model includes essential fields like username, password, email, and permissions, making it suitable for most web applications.
# models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
date_of_birth = models.DateField(null=True, blank=True)
phone_number = models.CharField(max_length=15, blank=True)
# Custom property example
@property
def full_name(self):
return f"{self.first_name} {self.last_name}"
def __str__(self):
return self.usernameSlide 3: Authentication Views Setup
The core of Django's authentication system lies in its views. These handle user login, logout, and session management. Here's a comprehensive setup of authentication views with proper security measures.
# views.py
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
@login_required
def index(request):
return render(request, 'index.html', {'user': request.user})
def login_view(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('index')
else:
messages.error(request, 'Invalid credentials')
return render(request, 'login.html')
def logout_view(request):
logout(request)
messages.success(request, 'Successfully logged out')
return redirect('login')Slide 4: URL Configuration for Authentication
The URL configuration maps authentication views to specific URLs, creating a coherent flow for user authentication processes. This setup includes both function-based and class-based views.
# urls.py
from django.urls import path
from . import views
from django.contrib.auth import views as auth_views
urlpatterns = [
path('', views.index, name='index'),
path('login/', views.login_view, name='login'),
path('logout/', views.logout_view, name='logout'),
path('password_reset/', auth_views.PasswordResetView.as_view(),
name='password_reset'),
path('password_reset/done/',
auth_views.PasswordResetDoneView.as_view(),
name='password_reset_done'),
]Slide 5: Login Template Implementation
Creating a secure and user-friendly login template is crucial for authentication. This implementation includes CSRF protection, form validation, and error messaging for enhanced security.
# templates/login.html
{% extends 'base.html' %}
{% block content %}
<form method="post" class="login-form">
{% csrf_token %}
{% if messages %}
<div class="messages">
{% for message in messages %}
<div class="{{ message.tags }}">
{{ message }}
</div>
{% endfor %}
</div>
{% endif %}
<div class="form-group">
<label for="username">Username:</label>
<input type="text" name="username" required>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" name="password" required>
</div>
<button type="submit">Login</button>
</form>
{% endblock %}Slide 6: User Registration Implementation
A secure user registration system is essential for any web application. This implementation includes form validation, password hashing, and email verification capabilities while following Django's security best practices.
# forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class CustomUserRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
first_name = forms.CharField(max_length=30, required=True)
last_name = forms.CharField(max_length=30, required=True)
class Meta:
model = User
fields = ['username', 'email', 'first_name', 'last_name',
'password1', 'password2']
def save(self, commit=True):
user = super().save(commit=False)
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
if commit:
user.save()
return userSlide 7: Registration View Implementation
The registration view handles user creation, validation, and initial setup. This implementation includes proper error handling and success messaging for a smooth user experience.
# views.py
from django.views.generic import CreateView
from django.contrib.auth import login
from django.shortcuts import render, redirect
from .forms import CustomUserRegistrationForm
def register_view(request):
if request.method == 'POST':
form = CustomUserRegistrationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
messages.success(request, 'Registration successful!')
return redirect('index')
else:
form = CustomUserRegistrationForm()
return render(request, 'registration/register.html',
{'form': form})Slide 8: Password Management System
Django's password management system includes robust features for password reset, change, and validation. This implementation showcases the complete password management workflow.
# settings.py
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 9,
}
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Custom password reset configuration
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your-email@gmail.com'
EMAIL_HOST_PASSWORD = 'your-app-specific-password'Slide 9: Custom Authentication Backend
Creating a custom authentication backend allows for flexible authentication methods beyond the traditional username/password combination, such as email-based authentication or social media integration.
# backends.py
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.db.models import Q
class EmailOrUsernameModelBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
# Allow authentication with either username or email
user = UserModel.objects.get(
Q(username__iexact=username) |
Q(email__iexact=username)
)
if user.check_password(password):
return user
except UserModel.DoesNotExist:
return None
def get_user(self, user_id):
UserModel = get_user_model()
try:
return UserModel.objects.get(pk=user_id)
except UserModel.DoesNotExist:
return NoneSlide 10: Session Management
Django's session management system provides secure user session handling with configurable settings for session duration, cookie security, and session storage options.
# settings.py
# Session configuration
SESSION_COOKIE_AGE = 1209600 # 2 weeks in seconds
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_COOKIE_SECURE = True # Only send over HTTPS
SESSION_COOKIE_HTTPONLY = True # Prevent JavaScript access
SESSION_COOKIE_SAMESITE = 'Lax'
# Custom middleware for session handling
from django.contrib.sessions.middleware import SessionMiddleware
class CustomSessionMiddleware(SessionMiddleware):
def process_request(self, request):
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
request.session = self.SessionStore(session_key)
def process_response(self, request, response):
try:
modified = request.session.modified
empty = request.session.is_empty()
except AttributeError:
return response
if empty:
response.delete_cookie(settings.SESSION_COOKIE_NAME)
else:
if modified or settings.SESSION_SAVE_EVERY_REQUEST:
request.session.save()
return responseSlide 11: Permissions and Groups Management
Django's permission system provides granular control over user access rights. This implementation demonstrates how to create custom permissions, manage user groups, and implement role-based access control.
# models.py
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
class Meta:
permissions = [
("can_publish_article", "Can publish articles"),
("can_edit_others_articles", "Can edit others articles"),
]
# Custom permission setup
def create_custom_permissions():
content_type = ContentType.objects.get_for_model(Article)
Permission.objects.create(
codename='can_archive_article',
name='Can archive articles',
content_type=content_type,
)
# Create editor group with permissions
editor_group, created = Group.objects.get_or_create(name='Editors')
permissions = Permission.objects.filter(
content_type=content_type,
codename__in=['can_publish_article', 'can_edit_others_articles']
)
editor_group.permissions.add(*permissions)Slide 12: Decorators for Access Control
Custom decorators provide a clean way to implement access control across views. This implementation shows how to create and use permission-based decorators.
# decorators.py
from django.core.exceptions import PermissionDenied
from django.contrib.auth.decorators import user_passes_test
from functools import wraps
def group_required(group_name):
def decorator(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
if request.user.groups.filter(name=group_name).exists():
return view_func(request, *args, **kwargs)
raise PermissionDenied
return wrapper
return decorator
def multiple_permissions_required(permission_list):
def decorator(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
if request.user.has_perms(permission_list):
return view_func(request, *args, **kwargs)
raise PermissionDenied
return wrapper
return decorator
# Usage example
@group_required('Editors')
@multiple_permissions_required(['myapp.can_publish_article'])
def publish_article(request, article_id):
# View logic here
passSlide 13: Token Authentication Implementation
Token-based authentication is crucial for API security. This implementation shows how to set up token authentication with custom token generation and validation.
# models.py
from django.conf import settings
from django.db import models
import binascii
import os
class Token(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='auth_token'
)
key = models.CharField(max_length=40, unique=True)
created = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
if not self.key:
self.key = self.generate_key()
return super().save(*args, **kwargs)
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
def __str__(self):
return self.key
# Authentication backend for token auth
from django.contrib.auth.backends import BaseBackend
class TokenBackend(BaseBackend):
def authenticate(self, request, token=None):
try:
token_obj = Token.objects.get(key=token)
return token_obj.user
except Token.DoesNotExist:
return NoneSlide 14: Security Middleware Implementation
Custom security middleware adds extra layers of protection to Django's authentication system. This implementation includes request validation and security headers.
# middleware.py
from django.conf import settings
from django.http import HttpResponseForbidden
import re
class SecurityMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Check for suspicious patterns
if self.is_suspicious_request(request):
return HttpResponseForbidden()
response = self.get_response(request)
# Add security headers
response['X-Content-Type-Options'] = 'nosniff'
response['X-Frame-Options'] = 'DENY'
response['Strict-Transport-Security'] = 'max-age=31536000'
return response
def is_suspicious_request(self, request):
suspicious_patterns = [
r'(?i)(<script|alert\(|eval\()',
r'(?i)(union.*select)',
r'(?i)(../../)',
]
for pattern in suspicious_patterns:
if re.search(pattern, request.path):
return True
if request.GET and any(
re.search(pattern, v)
for v in request.GET.values()
):
return True
return FalseSlide 15: Additional Resources
- https://arxiv.org/abs/2103.00373 - "Security Analysis of Django-Based Web Applications"
- https://arxiv.org/abs/1907.11975 - "A Systematic Analysis of the Django Web Framework"
- https://arxiv.org/abs/2009.01631 - "Authentication and Authorization in Modern Web Applications"
- https://arxiv.org/abs/2105.14619 - "Security Best Practices in Django Framework"