Django_010: Simple Login and Logout with Built-in Authentication
In this post, I am going to provide the most basic and simple form of login and logout using Django’s built-in methods: authenticate, login, and logout. I’ve kept it as minimal as possible to focus on the core concepts, without any CSS or fancy pages, just the essential functionality for login and logout.
Basic Explanation
Goal: A simple Django app with login/logout using Django’s built-in authentication.
Key Functions:
- authenticate(request, username, password): Verifies user credentials.
- login(request, user): Starts a user session.
- logout(request): Ends the user session.
Flow:
- Home page shows login status.
- Login page accepts username/password, uses authenticate and login.
- Logout ends the session with logout and redirects to home.
Step 1: Create and Set Up the Project
Run these commands in your terminal (Linux/Mac) or command prompt (Windows), you can check my previous posts for complete guide.
python -m venv env
source env/bin/activate # Windows: env\Scripts\activate
pip install django
django-admin startproject myproject
cd myproject
python manage.py startapp accounts
python manage.py migrate
python manage.py createsuperuser # Create a user (e.g., username: testuser, password: testpass123)Step 2: Project Files
Create or replace the following files in the myproject directory. I’ll list each file’s content and its path clearly.
File: myproject/settings.py
In myproject/settings.py, add ‘accounts’ to INSTALLED_APPS to register the accounts app, allowing Django to recognize its models, views, and URLs. In the TEMPLATES setting, add ‘DIRS’: [‘templates’] to tell Django to look for template files in the myproject/templates/ directory.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'accounts', # Our app
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'], # Look for templates in project-level templates folder
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', # For user info in templates
'django.contrib.messages.context_processors.messages', # For error messages
],
},
},
]
File: myproject/urls.py
In myproject/urls.py, include path(‘’, include(‘accounts.urls’)) in urlpatterns to route all requests starting with the root URL (/) to the URLs defined in the accounts app, enabling the app’s URL patterns to handle requests like /login/ and /logout/.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('accounts.urls')), # Route to accounts app
]File: accounts/urls.py
In accounts/urls.py, define urlpatterns with path(‘’, views.home, name=’home’) to route the root URL (/) to the home view,
- path(‘login/’, views.login_view, name=’login’) to route /login/ to the login view,
- path(‘logout/’, views.logout_view, name=’logout’) to route /logout/ to the logout view, mapping URLs to their respective view functions in the accounts app.
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'), # Home page
path('login/', views.login_view, name='login'), # Login page
path('logout/', views.logout_view, name='logout'), # Logout action
]File: accounts/views.py
In accounts/views.py, the file defines view functions that handle HTTP requests for the home page, login, and logout processes in the accounts app.
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
def home(request):
return render(request, 'home.html')
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('home')
else:
messages.error(request, 'Invalid username or password.')
return render(request, 'login.html')
def logout_view(request):
logout(request)
return redirect('home')1. home View
- This is the simplest view that just displays the home page
render()takes the request and a template name ('home.html') and returns that page to the user- It doesn’t require any authentication — anyone can see the home page
2. login_view View
At the end of this post, I’ve included a complete guide to the authenticate() process in Django.
This handles user login with several steps:
- Checks if the request method is POST (form submission)
2. Gets the username and password from the submitted form data
3. Uses Django’s authenticate() to verify credentials:
- If valid:
authenticate()returns a User object - If invalid: returns
None
4. For valid users:
login()creates a user session (logs them in)- Redirects to the home page
5. For invalid credentials:
- Shows an error message using Django’s messaging framework
6. For GET requests (initial page load) or after failed login:
- Shows the login form page (‘login.html’)
3. logout_view View
This handles user logout:
- Calls Django’s
logout()function which:
- Ends the user’s session
- Clears their authentication data
2. Redirects them back to the home page
File: templates/base.html (Create a templates folder in the myproject directory)
<!DOCTYPE html>
<html>
<head>
<title>Simple Auth</title>
</head>
<body>
{% if user.is_authenticated %}
<p>Hello, {{ user.username }}! <a href="{% url 'logout' %}">Logout</a></p>
{% else %}
<p><a href="{% url 'login' %}">Login</a></p>
{% endif %}
{% block content %}
{% endblock %}
</body>
</html>In templates/base.html, this file serves as the base template that other templates—such as home.html and login.html—extend. It provides a common layout, including a navigation section.
The code {% if user.is_authenticated %}<p>Hello, {{ user.username }}! <a href="{% url 'logout' %}">Logout</a></p>{% else %}<p><a href="{% url 'login' %}">Login</a></p>{% endif %} checks whether the user is logged in:
- If
user.is_authenticatedisTrue, it displays the username along with a logout link. - If it is
False, it shows a login link instead.
The user.is_authenticated variable is part of Django’s authentication system. It is made available in templates by the django.contrib.auth.context_processors.auth context processor, which is listed in myproject/settings.py under TEMPLATES['OPTIONS']['context_processors']. This processor ensures the user object—with authentication status and user details—is accessible in all templates when a request is processed.
Get CodeAddict’s stories in your inbox
Join Medium for free to get updates from this writer.
File: templates/home.html
{% extends 'base.html' %}
{% block content %}
<h1>Home</h1>
{% if user.is_authenticated %}
<p>You are logged in!</p>
{% else %}
<p>You are not logged in.</p>
{% endif %}
{% endblock %}File: templates/login.html
{% extends 'base.html' %}
{% block content %}
<h1>Login</h1>
{% if messages %}
{% for message in messages %}
<p style="color: red;">{{ message }}</p>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<label>Username:</label>
<input type="text" name="username">
<label>Password:</label>
<input type="password" name="password">
<button type="submit">Login</button>
</form>
{% endblock %}Step 3: Run the Project
python manage.py runserverStep 4: Test the App
- Open http://127.0.0.1:8000/ in your browser.
- Home Page: Shows if you’re logged in or not.
- Login Page: Go to /login/, use the superuser credentials (e.g., testuser/testpass123).
- Logout: Click the “Logout” link when logged in to end the session.
Additional Explanation (Advanced): Django Authentication
Predefined Functions in Django
authenticate()- Django's built-in authentication function
- Location:
django.contrib.auth.authenticate - Purpose: Verifies user credentials against the database
- Returns: User object if valid, None if invalid
2. login() - Django's session creation function
- Location:
django.contrib.auth.login - Purpose: Creates a persistent user session
- Stores session data in the database and browser cookies
3. logout() - Django's session termination function
- Location:
django.contrib.auth.logout - Purpose: Destroys the user session
How Authentication Works Step-by-Step
1. Database Setup (Behind the Scenes)
Django automatically creates these important tables during migration:
- auth_user — Stores all user accounts (username, password hash, email, etc.)
- auth_session — Stores active user sessions
2. The Authentication Process
When a user submits the login form:
- Form Submission (POST request)
username = request.POST['username']
password = request.POST['password']- The browser sends the username and password to the server
2. Credential Verification
user = authenticate(request, username=username, password=password)- Django queries the
auth_usertable for the username - If found, it hashes the provided password and compares it with the stored hash
- Password hashing uses PBKDF2 by default (with salt and multiple iterations)
3. User Object Creation
- If credentials match, Django returns a User object containing: => User ID, Username, Email, First/last name, Permissions, Other profile data
4. Session Creation
login(request, user)- Creates a session record in the
auth_sessiontable - Sets a session cookie in the browser containing the session ID
- The session ID is a random, hard-to-guess string
5. Database Operations
- For authentication:
SELECT * FROM auth_user WHERE username = '[provided_username]';- For session creation:
INSERT INTO auth_session (session_key, session_data, expire_date) VALUES ('random_session_id', 'encrypted_session_data', 'expiration_time');3. Session Management
After successful login: Each subsequent request includes the session cookie
Django:
- Reads the session ID from the cookie
- Looks it up in the
auth_sessiontable - Attaches the authenticated user to the
requestobject (available asrequest.user)
5. Logout Process
logout(request)- Deletes the session record from the database
- Tells the browser to expire the session cookie
- Clears the user data from the request object
Customization Options
While Django provides these defaults, you can customize:
- Authentication Backends — To authenticate against different sources (LDAP, etc.)
- User Model — To add custom fields to users
- Password Hashers — To use different hashing algorithms
- Session Engine — To store sessions in cache or other systems
The beauty of Django’s auth system is that it handles all these complex security concerns for you while providing sensible defaults that work for most applications.
How Django Authentication Connects Users, Views, and Templates (Step-by-Step)
The {% if user.is_authenticated %} in templates/base.html checks if a user is logged in, and the user object is sent to templates through Django’s authentication system. Here’s a simple explanation of the process and where users are created:
User Creation:
- Users are created in the database using Django’s authentication system (django.contrib.auth). You create a user via python manage.py createsuperuser (for admins) or through code/models (e.g., User.objects.create_user(username='testuser', password='testpass123')). These users are stored in the database table managed by Django’s auth.User model.
Authentication Process:
- In accounts/views.py, the login_view uses authenticate(request, username, password) to verify the user’s credentials against the database.
If valid, login(request, user) creates a session, marking the user as authenticated and attaching their User object to the request.
Sending User to Templates:
— In myproject/settings.py, the TEMPLATES setting includes 'django.contrib.auth.context_processors.auth' in context_processors.
This context processor automatically adds the user object (containing is_authenticated and details like username) to every template’s context when a view renders a template (e.g., render(request, 'home.html')).
As a result, {% if user.is_authenticated %} in base.html can check if the user is logged in and access user.username.
Flow Summary:
- User is created in the database (via
createsuperuseror code). - User logs in via
login_view, which authenticates and sets the session. - The auth context processor in
settings.pysends theuserobject to templates. - Templates use
user.is_authenticatedto show content based on login status.






