Skip to main content

Django: Built-in Authentication System

Django: Built-in Authentication System

Django’s built-in authentication system provides a robust and secure framework for managing user authentication and authorization in web applications. Integrated within Django’s Model-View-Template (MVT) architecture, it offers tools for user login, logout, registration, and permission management, reducing the need for custom solutions. This tutorial explores Django’s authentication system, covering its setup, customization, and practical applications for secure user management.


01. What Is Django’s Authentication System?

Django’s authentication system, part of the django.contrib.auth package, handles user authentication (verifying identity) and authorization (controlling access). It includes models like User and Group, views for login/logout, and utilities for password management. Ideal for applications like blogs, e-commerce platforms, or dashboards, it leverages Django’s ORM for seamless database integration.

Example: Basic Authentication Setup

# myproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
]

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('django.contrib.auth.urls')),
]

# Create a superuser
python manage.py createsuperuser

Output:

Login page accessible at http://127.0.0.1:8000/accounts/login/.

Explanation:

  • django.contrib.auth - Enables authentication features.
  • include('django.contrib.auth.urls') - Adds built-in authentication URLs (e.g., login, logout).

02. Key Authentication Concepts

The authentication system provides a comprehensive set of tools for user management. The table below summarizes key components and their roles in web development:

Component Description Use Case
User Model Represents users with attributes like username, email Store user data
Authentication Views Built-in views for login, logout, password reset Handle user sessions
Permissions Controls access to models and actions Restrict functionality by role
Groups Collections of permissions for user roles Simplify permission management


2.1 Using Built-in Authentication Views

Example: Setting Up Login and Logout

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('django.contrib.auth.urls')),
]

# myapp/templates/registration/login.html
{% extends "base.html" %}
{% block content %}
    <h2>Login</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Login</button>
    </form>
{% endblock %}

Output:

Custom login page at http://127.0.0.1:8000/accounts/login/.

Explanation:

  • django.contrib.auth.urls - Includes URLs like login/, logout/.
  • Custom template overrides default login form styling.

2.2 Restricting Access with Decorators

Example: Protecting Views

# myapp/views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render

@login_required
def dashboard(request):
    return render(request, 'myapp/dashboard.html', {'user': request.user})

# myapp/templates/myapp/dashboard.html
{% extends "base.html" %}
{% block content %}
    <h2>Welcome, {{ user.username }}!</h2>
    <p>This is your dashboard.</p>
{% endblock %}

Output:

Unauthenticated users redirected to http://127.0.0.1:8000/accounts/login/?next=/dashboard/.

Explanation:

  • login_required - Restricts view access to authenticated users.
  • Redirects to login page with next parameter for post-login navigation.

2.3 Managing Permissions

Example: Custom Permissions

# myapp/models.py
from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)

    class Meta:
        permissions = [
            ("can_publish", "Can publish articles"),
        ]

# myapp/views.py
from django.contrib.auth.decorators import permission_required
from django.shortcuts import render

@permission_required('myapp.can_publish')
def publish_article(request):
    return render(request, 'myapp/publish.html')

Output:

Only users with 'can_publish' permission access http://127.0.0.1:8000/publish/.

Explanation:

  • permissions - Defines custom permissions in model Meta.
  • permission_required - Restricts view access to users with specified permission.

2.4 User Registration

Example: Custom Registration View

# myapp/forms.py
from django import forms
from django.contrib.auth.models import User

class RegisterForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput)
    password_confirm = forms.CharField(widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ['username', 'email', 'password']

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

# myapp/views.py
from django.shortcuts import render, redirect
from .forms import RegisterForm

def register(request):
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.set_password(form.cleaned_data['password'])
            user.save()
            return redirect('login')
    else:
        form = RegisterForm()
    return render(request, 'myapp/register.html', {'form': form})

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('register/', views.register, name='register'),
]

Output:

Registration form at http://127.0.0.1:8000/register/ creates new users.

Explanation:

  • set_password - Securely hashes the user’s password.
  • Custom form validates password confirmation.

2.5 Incorrect Authentication Usage

Example: Bypassing Authentication Check

# myapp/views.py (Incorrect)
from django.shortcuts import render

def dashboard(request):
    # No authentication check
    return render(request, 'myapp/dashboard.html', {'user': request.user})

Output:

Unauthenticated users can access http://127.0.0.1:8000/dashboard/.

Explanation:

  • Omitting login_required exposes sensitive views.
  • Solution: Use @login_required or check request.user.is_authenticated.

03. Effective Usage

3.1 Recommended Practices

  • Leverage built-in views and decorators to minimize custom authentication code.

Example: Comprehensive Authentication Setup

# myproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
]
LOGIN_REDIRECT_URL = 'dashboard'
LOGOUT_REDIRECT_URL = 'login'

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('django.contrib.auth.urls')),
    path('', include('myapp.urls')),
]

# myapp/views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render

@login_required
def dashboard(request):
    return render(request, 'myapp/dashboard.html', {'user': request.user})

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('dashboard/', views.dashboard, name='dashboard'),
]

# myapp/templates/myapp/dashboard.html
{% extends "base.html" %}
{% block content %}
    <h2>Welcome, {{ user.username }}!</h2>
    <p>Email: {{ user.email }}</p>
    <a href="{% url 'logout' %}">Logout</a>
{% endblock %}

Output:

Secure dashboard at http://127.0.0.1:8000/dashboard/ for authenticated users.
  • LOGIN_REDIRECT_URL - Directs users post-login.
  • Built-in views handle authentication securely.

3.2 Practices to Avoid

  • Avoid storing plain-text passwords or bypassing built-in security features.

Example: Storing Plain-Text Passwords

# myapp/views.py (Incorrect)
from django.contrib.auth.models import User
from django.shortcuts import redirect

def register(request):
    username = request.POST['username']
    password = request.POST['password']  # Incorrect: Plain text
    User.objects.create(username=username, password=password)
    return redirect('login')

Output:

Passwords stored unhashed, vulnerable to breaches.
  • Plain-text passwords compromise security.
  • Solution: Use set_password for secure hashing.

04. Common Use Cases

4.1 User Login for Blog Access

Restrict blog content to authenticated users.

Example: Protected Blog View

# myapp/views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from .models import Post

@login_required
def blog(request):
    posts = Post.objects.all()
    return render(request, 'myapp/blog.html', {'posts': posts})

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('blog/', views.blog, name='blog'),
]

Output:

Blog at http://127.0.0.1:8000/blog/ requires login.

Explanation:

  • login_required - Ensures only logged-in users view posts.
  • Integrates with built-in login view.

4.2 Role-Based Dashboard Access

Provide role-specific dashboards using permissions.

Example: Editor Dashboard

# myapp/views.py
from django.contrib.auth.decorators import permission_required
from django.shortcuts import render
from .models import Article

@permission_required('myapp.can_publish')
def editor_dashboard(request):
    articles = Article.objects.filter(author=request.user)
    return render(request, 'myapp/editor_dashboard.html', {'articles': articles})

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('editor/', views.editor_dashboard, name='editor_dashboard'),
]

# myapp/templates/myapp/editor_dashboard.html
{% extends "base.html" %}
{% block content %}
    <h2>Editor Dashboard</h2>
    <ul style="padding: 0px 0px 0px 20px; margin-top: 0px;">
    {% for article in articles %}
        <li>{{ article.title }}</li>
    {% endfor %}
    </ul>
{% endblock %}

Output:

Editors access their articles at http://127.0.0.1:8000/editor/.

Explanation:

  • permission_required - Limits access to users with can_publish.
  • Filters articles by user for role-specific data.

Conclusion

Django’s built-in authentication system, integrated with the Model-View-Template architecture, provides a secure and efficient framework for user management. Key takeaways:

  • Use built-in views and URLs for quick authentication setup.
  • Secure views with login_required and permission_required decorators.
  • Implement custom registration with secure password handling.
  • Avoid insecure practices like plain-text passwords.
  • SAEul>

    With Django’s authentication system, you can build secure, user-friendly web applications with minimal effort!

Comments