Learn how to create a simple and secure authentication system in Django. Follow this step-by-step guide for login and registration. Perfect for beginners.
Creating an authentication system in Django is essential for any web application that requires user accounts. This guide will walk you through the process of setting up a simple and secure login and registration system using Django. Whether you're a beginner or looking to refresh your skills, this step-by-step tutorial will help you implement user authentication in your Django project effortlessly.
Prerequisites
Before we dive in, make sure you have a basic understanding of Django and web development. You'll need the following tools and libraries installed on your machine:
- Python (version 3.6 or higher)
- Django (version 3.0 or higher)
- A text editor or IDE (such as VS Code or PyCharm)
- Basic knowledge of HTML and CSS
Setting Up the Development Environment
Installing Django
Before starting, ensure you have Python installed. You can install Django using pip:
pip install django
Creating a new Django project
Create a new Django project using the following command:
django-admin startproject auth_system
Setting up the project structure
Navigate into your project directory:
cd auth_system
Create a Django App
Create a new app within your project:
python manage.py startapp accounts
Adding the app to the project
In auth_system/settings.py
, add accounts
to the INSTALLED_APPS
list:
INSTALLED_APPS = [ 'accounts', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
Creating the Authentication System
Create Forms
In accounts, create a new file named forms.py and add the following function:
from django import forms from django.contrib.auth.models import User from django.contrib.auth.forms import UserCreationForm class RegisterForm(UserCreationForm): email = forms.EmailField(required=True) class Meta: model = User fields = ['username', 'email', 'password1', 'password2']
Creating the Views
Next, we’ll create views to handle registration and login system. Open accounts/views.py
and add the following:
from django.shortcuts import render, redirect from django.contrib.auth import login, authenticate, logout from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.decorators import login_required from django.contrib import messages from .forms import RegisterForm def register(request): if request.method == 'POST': form = RegisterForm(request.POST) if form.is_valid(): form.save() username = form.cleaned_data.get('username') password = form.cleaned_data.get('password1') user = authenticate(username=username, password=password) login(request, user) return redirect('auth_login') else: messages.error(request, 'Registration failed. Please correct the errors below.') else: form = RegisterForm() return render(request, 'register.html', {'form': form}) def user_login(request): if request.method == 'POST': form = AuthenticationForm(request, data=request.POST) if form.is_valid(): username = form.cleaned_data.get('username') password = form.cleaned_data.get('password') user = authenticate(username=username, password=password) if user is not None: login(request, user) return redirect('auth_welcome') else: messages.error(request, 'Invalid username or password.') else: messages.error(request, 'Invalid username or password.') else: form = AuthenticationForm() return render(request, 'login.html', {'form': form}) @login_required def welcome(request): return render(request, 'welcome.html') def logout_view(request): logout(request) return redirect('auth_login')
Set Up URL Routing
Add a URL pattern for your view. In accounts/urls.py (create this file if it doesn't exist), add:
from django.urls import path from django.shortcuts import redirect from . import views urlpatterns = [ path('', lambda request: redirect('auth_login')), path('register/', views.register, name='auth_register'), path('login/', views.user_login, name='auth_login'), path('welcome/', views.welcome, name='auth_welcome'), path('logout/', views.logout_view, name='auth_logout'), ]
Include the app's URLs in your project's URL configuration. Open auth_system/urls.py and include the auth app URLs:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('accounts.urls')), ]
Create Templates
Create templates for registration, login, and welcome in accounts/templates/
.
register.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Register</title> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; background: #1f1d2b; font-family: 'Poppins', sans-serif; margin: 0; } .form-container { background: #fff; padding: 3rem; border-radius: 15px; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); animation: bounceIn 1s ease-out; width: 400px; } .form-container h2 { text-align: center; margin-bottom: 2rem; color: #333; font-weight: bold; text-transform: uppercase; } .form-container form { display: flex; flex-direction: column; } .form-group { position: relative; margin-bottom: 1.5rem; } .form-group input { width: -webkit-fill-available; padding: 1rem; padding-left: 2rem; border: 1px solid #ddd; border-radius: 5px; transition: all 0.3s ease; } .form-group input:focus { border-color: #007bff; box-shadow: 0 0 5px rgba(0, 123, 255, 0.5); } .form-group label { position: absolute; top: 50%; left: 2rem; transform: translateY(-50%); color: #aaa; font-size: 1rem; pointer-events: none; transition: all 0.3s ease; } .form-group input:focus + label, .form-group input:not(:placeholder-shown) + label { top: 0; left: 1rem; transform: translateY(-50%); background: #fff; padding: 0 0.25rem; color: #007bff; font-size: 0.8rem; } .form-group i { position: absolute; top: 50%; left: 0.75rem; transform: translateY(-50%); color: #aaa; } button { padding: 1rem; background: #007bff; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 1rem; transition: background 0.3s ease; } button:hover { background: #0056b3; } @keyframes bounceIn { from { opacity: 0; transform: scale(0.5); } to { opacity: 1; transform: scale(1); } } .error { color: red; font-size: 0.9rem; margin-bottom: 1rem; } .error ul{ margin: 0; } </style> </head> <body> <div class="form-container"> <h2>Register</h2> {% if messages %} {% for message in messages %} <div class="error">{{ message }}</div> {% endfor %} {% endif %} <form method="post"> {% csrf_token %} <div class="form-group"> <input type="text" id="username" name="username" required placeholder=" "> <label for="username">Username</label> <i class="fas fa-user"></i> </div> {% if form.username.errors %} <div class="error">{{ form.username.errors }}</div> {% endif %} <div class="form-group"> <input type="email" id="email" name="email" required placeholder=" "> <label for="email">Email</label> <i class="fas fa-envelope"></i> </div> {% if form.email.errors %} <div class="error">{{ form.email.errors }}</div> {% endif %} <div class="form-group"> <input type="password" id="password1" name="password1" required placeholder=" "> <label for="password1">Password</label> <i class="fas fa-lock"></i> </div> {% if form.password1.errors %} <div class="error">{{ form.password1.errors }}</div> {% endif %} <div class="form-group"> <input type="password" id="password2" name="password2" required placeholder=" "> <label for="password2">Confirm Password</label> <i class="fas fa-lock"></i> </div> {% if form.password2.errors %} <div class="error">{{ form.password2.errors }}</div> {% endif %} <button type="submit">Register</button> </form> <p>Have an Account? <a href="http://127.0.0.1:8000/login/">Login Here</a> </div> </body> </html>
login.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Login</title> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; background: #1f1d2b; font-family: 'Poppins', sans-serif; margin: 0; } .form-container { background: #fff; padding: 3rem; border-radius: 15px; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); animation: slideIn 1s ease-out; width: 400px; } .form-container h2 { text-align: center; margin-bottom: 2rem; color: #333; font-weight: bold; text-transform: uppercase; } .form-container form { display: flex; flex-direction: column; } .form-group { position: relative; margin-bottom: 1.5rem; } .form-group input { width: -webkit-fill-available; padding: 1rem; padding-left: 2rem; border: 1px solid #ddd; border-radius: 5px; transition: all 0.3s ease; } .form-group input:focus { border-color: #28a745; box-shadow: 0 0 5px rgba(40, 167, 69, 0.5); } .form-group label { position: absolute; top: 50%; left: 2rem; transform: translateY(-50%); color: #aaa; font-size: 1rem; pointer-events: none; transition: all 0.3s ease; } .form-group input:focus + label, .form-group input:not(:placeholder-shown) + label { top: 0; left: 1rem; transform: translateY(-50%); background: #fff; padding: 0 0.25rem; color: #28a745; font-size: 0.8rem; } .form-group i { position: absolute; top: 50%; left: 0.75rem; transform: translateY(-50%); color: #aaa; } button { padding: 1rem; background: #28a745; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 1rem; transition: background 0.3s ease; } button:hover { background: #218838; } @keyframes slideIn { from { opacity: 0; transform: translateX(-100px); } to { opacity: 1; transform: translateX(0); } } .error { color: red; font-size: 0.9rem; margin-bottom: 1rem; } .error ul { margin: 0; } </style> </head> <body> <div class="form-container"> <h2>Login</h2> {% if messages %} <div class="error"> {% for message in messages %} <p>{{ message }}</p> {% endfor %} </div> {% endif %} <form method="post"> {% csrf_token %} <div class="form-group"> <input type="text" id="username" name="username" required placeholder=" "> <label for="username">Username</label> <i class="fas fa-user"></i> </div> {% if form.username.errors %} <div class="error">{{ form.username.errors }}</div> {% endif %} <div class="form-group"> <input type="password" id="password" name="password" required placeholder=" "> <label for="password">Password</label> <i class="fas fa-lock"></i> </div> {% if form.password.errors %} <div class="error">{{ form.password.errors }}</div> {% endif %} <button type="submit">Login</button> </form> <p>Not a member? <a href="http://127.0.0.1:8000/register/">Sign up now</a> </div> </body> </html>
welcome.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Welcome</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; background: #1f1d2b; color: #fff; font-family: 'Poppins', sans-serif; margin: 0; } .welcome-container { text-align: center; } </style> </head> <body> <div class="welcome-container"> <h1>Welcome, {{ user.username }}!</h1> <p>You have successfully logged in.</p> <a href="{% url 'auth_logout' %}" style="color: #007bff; text-decoration: none;">Logout</a> </div> </body> </html>
Run Your Server
Apply migrations and run your server:
python manage.py migrate python manage.py runserver
Open your browser and go to http://127.0.0.1:8000/ to see your authentication application in action.
Full Authentication App Project Structure
auth_system/ ├── auth_system/ │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── accounts/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations/ │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ ├── views.py │ └── templates/ │ ├── login.html │ ├── register.html │ └── welcome.html ├── manage.py └── requirements.txt
Conclusion
By following this guide, you have successfully created a basic authentication system in Django. This includes user registration and login functionality. With these foundations in place, you can further customize and expand your system to meet the specific needs of your application. Secure user authentication is a crucial aspect of web development, and mastering it will make your Django projects more robust and user-friendly.
That’s a wrap!
I hope you enjoyed this article
Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.
And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!
Thanks!
Faraz 😊