Skip to main content
Django Basics Tutorial
CHAPTER 12 Beginner

User Authentication and Authorization

Updated: May 14, 2026
35 min read

# CHAPTER 12

User Authentication and Authorization

1. Introduction

A major reason companies choose Django is its robust, built-in Authentication system. Building secure login systems, managing user sessions, and cryptographically hashing passwords is incredibly difficult and dangerous to write from scratch. Django provides these features out of the box. In this chapter, we will learn how to create user registration forms, implement login and logout views, and restrict specific pages using authorization decorators.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Use Django's built-in UserCreationForm to register new users.
  • Configure Django's built-in Login and Logout views.
  • Understand the difference between Authentication and Authorization.
  • Protect Views using the @loginrequired decorator.

3. Beginner-Friendly Explanation

Imagine an exclusive country club.
  • Registration: A person fills out paperwork to become a member. Their name is added to the ledger, and they are given an ID card.
  • Authentication (Login): The person shows their ID card to the front gate. The guard verifies they are on the list and lets them onto the grounds.
  • Authorization (Permissions): The person tries to enter the VIP kitchen. The kitchen door has a lock (@loginrequired). Even though the person is in the club, the kitchen lock checks their specific ID and says, "Employees only. Access Denied."

4. Step 1: User Registration

Django provides a built-in User model and a pre-built form called UserCreationForm. We don't even need to write forms.py!

In blog/views.py:

python
1234567891011121314151617181920
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages

def register(request):
    if request.method == 'POST':
        # Pass the POST data to the built-in form
        form = UserCreationForm(request.POST)
        if form.is_valid():
            # Automatically hashes the password and saves the User to the DB!
            form.save()
            
            # Send a temporary success flash message
            username = form.cleaned_data.get('username')
            messages.success(request, f'Account created for {username}! You can now log in.')
            return redirect('login')
    else:
        form = UserCreationForm()
        
    return render(request, 'users/register.html', {'form': form})

*(You will need to create the HTML template users/register.html rendering {{ form.as_p }} just like the previous chapter).*

5. Step 2: Login and Logout Views

Django's login system is so complete that you don't even need to write a View function. You simply import Django's built-in views into your urls.py.

In core/urls.py:

python
123456789101112131415
from django.urls import path
from django.contrib.auth import views as auth_views # Import built-in views
from blog import views as blog_views

urlpatterns = [
    # ... your other routes
    
    path('register/', blog_views.register, name='register'),
    
    # Use the built-in LoginView. Tell it where the HTML file is.
    path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
    
    # Use the built-in LogoutView.
    path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
]

*(Django expects the login HTML form to use POST and a {% csrf_token %}, similar to your register form).*

6. Step 3: Redirect Configuration

When a user successfully logs in, where should Django send them? You define this in your master settings.

In core/settings.py (add to the very bottom):

python
12345
# Where to go after logging in
LOGIN_REDIRECT_URL = 'blog-home'

# Where to send users if they try to access a protected page
LOGIN_URL = 'login'

7. Step 4: Authorization (Protecting Routes)

Now that users can log in, we want to restrict the "Create Post" page. Only authenticated users should be able to write blog posts.

In blog/views.py:

python
12345678910
from django.contrib.auth.decorators import login_required

# The Decorator acts as a security guard. It runs BEFORE the view function.
@login_required
def create_post(request):
    # This code will ONLY execute if the user is logged in!
    # If they are not logged in, Django redirects them to the 'LOGIN_URL'
    
    if request.method == 'POST':
        # ... logic from Chapter 11 ...

8. Backend Workflow: Template Authorization

You can also conditionally display HTML based on the user's authentication status using the request.user object, which is automatically injected into every template by Django.

In blog/base.html:

html
123456789101112
<nav>
    <a href="{% url &#039;blog-home' %}">Home</a>
    
    <!-- Check if the user is logged in -->
    {% if user.is_authenticated %}
        <a href="{% url &#039;post-create' %}">New Post</a>
        <a href="{% url &#039;logout' %}">Logout ({{ user.username }})</a>
    {% else %}
        <a href="{% url &#039;login' %}">Login</a>
        <a href="{% url &#039;register' %}">Register</a>
    {% endif %}
</nav>

9. Best Practices

  • Password Hashing: You will notice we never wrote code to hash the user's password. Django's UserCreationForm utilizes the PBKDF2 algorithm with a SHA256 hash by default. Never attempt to write your own password hashing algorithm.

10. Common Mistakes

  • Creating a Custom User Model Too Late: For simple apps, the built-in User model is fine. However, professional apps often require users to log in with an email instead of a username. If you need this, you MUST configure a Custom User Model *before* running your very first migration. Changing to a Custom User Model halfway through a project is a notoriously difficult database nightmare.

11. Exercises

  1. 1. Define the difference between "Authentication" and "Authorization". Which code snippet in this chapter represents Authorization?

12. Coding Challenges

  • Challenge: Protect the postdetail view using the @loginrequired decorator. Test it by opening an Incognito browser window and attempting to navigate directly to /post/1/. You should be redirected to the login page.

13. MCQs with Answers

Question 1

Which Django feature is used directly above a View function definition to restrict access strictly to users who have logged into the application?

Question 2

What is the primary benefit of utilizing Django's built-in authviews.LoginView inside your urls.py file?

14. Interview Questions

  • Q: Explain how Django manages user sessions under the hood after a successful login. How does the server "remember" the client on subsequent HTTP requests?
  • Q: Why is it considered a security risk to store passwords in plain text in a database? How does Django secure passwords by default?

15. FAQs

Q: Can I use third-party logins like "Log in with Google"? A: Yes! This is called OAuth. While Django doesn't do it natively, there is an incredibly popular, industry-standard package called django-allauth that plugs directly into Django to handle Google, GitHub, and Facebook logins seamlessly.

16. Summary

In Chapter 12, we secured our application by implementing user registration and authentication. By leveraging Django's massive suite of built-in tools (UserCreationForm, LoginView, LogoutView), we avoided writing dangerous custom security logic. Furthermore, we implemented strict Authorization rules by protecting our backend routes with the @login_required decorator and dynamically altering our frontend HTML based on the user's session state.

17. Next Chapter Recommendation

Our users are managed, but how does the site administrator manage the actual database records without writing SQL? Proceed to Chapter 13: Django Admin Panel.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·