DevDuniya
Mar 26, 2025
In this comprehensive guide, we'll walk through building a complete authentication system with Django that includes user registration, login functionality, and a protected dashboard. Django's built-in authentication system makes it remarkably easy to implement secure user management while maintaining flexibility for customization.
Django comes with a powerful built-in authentication system that provides:
This means you get enterprise-grade security without having to build everything from scratch.
Before we begin, ensure you have:
Let's start by creating our Django project and app.
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`
pip install django
django-admin startproject authsystem
cd authsystem
python manage.py startapp accounts
In authsystem/settings.py
, add 'accounts' to INSTALLED_APPS:
INSTALLED_APPS = [
...
'accounts',
'crispy_forms', # We'll use this for better form rendering
]
Install crispy_forms:
pip install django-crispy-forms
Add at the bottom of settings.py:
CRISPY_TEMPLATE_PACK = 'bootstrap4'
LOGIN_REDIRECT_URL = 'dashboard'
LOGOUT_REDIRECT_URL = 'home'
Django comes with SQLite configured by default, which is perfect for development. For production, you'd want to use PostgreSQL or MySQL.
Run initial migrations:
python manage.py migrate
While Django provides a default User model, it's often recommended to create a custom user model even if you're just starting, as it's difficult to switch later.
In accounts/models.py
:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# Add additional fields here if needed
pass
Update authsystem/settings.py
to use our custom user model:
AUTH_USER_MODEL = 'accounts.CustomUser'
Now create and run migrations:
python manage.py makemigrations
python manage.py migrate
In authsystem/urls.py
:
from django.contrib import admin
from django.urls import path, include
from django.views.generic.base import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accounts.urls')),
path('accounts/', include('django.contrib.auth.urls')),
path('', TemplateView.as_view(template_name='home.html'), name='home'),
]
Create accounts/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.SignUpView.as_view(), name='signup'),
path('dashboard/', views.DashboardView.as_view(), name='dashboard'),
]
In accounts/views.py
:
from django.shortcuts import render
from django.views.generic import CreateView, TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .forms import CustomUserCreationForm
class SignUpView(CreateView):
form_class = CustomUserCreationForm
success_url = '/accounts/login/'
template_name = 'registration/signup.html'
class DashboardView(LoginRequiredMixin, TemplateView):
template_name = 'dashboard.html'
Create accounts/forms.py
:
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = UserCreationForm.Meta.fields + ('email',) # Add email field
Django's authentication views look for templates in a registration
directory. Let's create our templates.
Create templates/base.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}Django Auth System{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="{% url 'home' %}">Django Auth</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
{% if user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{% url 'dashboard' %}">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'signup' %}">Sign Up</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
<div class="container mt-4">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endif %}
{% block content %}
{% endblock %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Create templates/home.html
:
{% extends 'base.html' %}
{% block content %}
<h1>Welcome to Django Authentication System</h1>
{% if user.is_authenticated %}
<p>Hello, {{ user.username }}! You're logged in.</p>
{% else %}
<p>Please login or sign up to access the dashboard.</p>
{% endif %}
{% endblock %}
Create templates/registration/signup.html
:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4>Sign Up</h4>
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary mt-3">Sign Up</button>
</form>
<p class="mt-3">Already have an account? <a href="{% url 'login' %}">Log In</a></p>
</div>
</div>
</div>
</div>
{% endblock %}
Create templates/registration/login.html
:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4>Log In</h4>
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary mt-3">Log In</button>
</form>
<p class="mt-3">Don't have an account? <a href="{% url 'signup' %}">Sign Up</a></p>
</div>
</div>
</div>
</div>
{% endblock %}
Create templates/dashboard.html
:
{% extends 'base.html' %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h4>Welcome to Your Dashboard, {{ user.username }}!</h4>
</div>
<div class="card-body">
<p>Email: {{ user.email }}</p>
<p>Last Login: {{ user.last_login }}</p>
<p>Date Joined: {{ user.date_joined }}</p>
<div class="mt-4">
<a href="{% url 'password_change' %}" class="btn btn-warning">Change Password</a>
<a href="{% url 'logout' %}" class="btn btn-danger">Log Out</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Start the development server:
python manage.py runserver
Visit http://localhost:8000
in your browser to see the application in action.
UserCreationForm
extended with email fieldLoginRequiredMixin
to restrict accessDjango's authentication system provides excellent security out of the box:
django-axes
Here are some ways to enhance this basic authentication system:
allauth
{% csrf_token %}
AUTH_USER_MODEL
is set correctlycollectstatic
in productionIn this tutorial, we've built a complete authentication system with Django that includes:
Django's built-in authentication system provides a robust foundation that can be easily extended to meet your specific requirements. The system we've built is secure, maintainable, and follows Django's best practices.
Remember that authentication is a critical component of any web application, and Django provides the tools to implement it securely and efficiently. Always keep security in mind when working with user authentication and consider additional security measures for production applications.