Menu

Django & Flask Topic

Introduction: Django Authentication vs. Authorization

  • Authentication (AuthN): "Who are you?" - Verifying a user's identity (e.g., through a username and password).

  • Authorization (AuthZ): "What are you allowed to do?" - Determining what permissions an authenticated user has.

Django's django.contrib.auth app, often called "the auth app," provides a complete system for both.


1. What is the django.contrib.auth app?

It's a built-in Django application that provides:

  • A User model for storing user credentials and profile information.

  • Views and URLs for login, logout, and password change.

  • Forms for user creation and authentication.

  • Decorators and Mixins to control access to views.

  • Low-level functions to handle the authentication process.

It's enabled by default in most Django projects. Check your INSTALLED_APPS and MIDDLEWARE in settings.py:

python

# myproject/settings.py
INSTALLED_APPS = [
    # ...
    'django.contrib.auth',  # Core authentication framework
    'django.contrib.contenttypes', # Needed by the auth app
    # ...
]

MIDDLEWARE = [
    # ...
    'django.contrib.sessions.middleware.SessionMiddleware', # Manages sessions across requests
    'django.contrib.auth.middleware.AuthenticationMiddleware', # Associates users with requests
    # ...
]

2. Key Concepts in Action

Let's build the core user flow: Sign Up (Registration), Log In, and Log Out.

The User Model

This is the heart of the system. You can import and use it directly.

python

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

# Create a new user
user = User.objects.create_user(
    username='johndoe',
    email='john@example.com',
    password='supersecretpassword'
)
# Important: Use create_user, not create, to ensure the password is hashed correctly.

# You can access its fields
print(user.username) # 'johndoe'
print(user.email)    # 'john@example.com'
print(user.date_joined) # The datetime when the user was created
print(user.is_staff) # False - Boolean for admin site access
print(user.is_superuser) # False - Boolean for all permissions

1. User Sign Up (Registration)

Django provides a form to make this easy. We'll create a view to handle the registration.

python

# myapp/views.py
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':
        # Form was submitted with data
        form = UserCreationForm(request.POST)
        if form.is_valid():
            # Save the new user to the database (with hashed password)
            user = form.save()
            # Log the user in immediately after registration
            # (We'll see the login function next)
            username = form.cleaned_data.get('username')
            messages.success(request, f'Account created for {username}! You can now log in.')
            return redirect('login') # Redirect to the login page
    else:
        # It's a GET request, so present a blank form
        form = UserCreationForm()
    
    return render(request, 'myapp/register.html', {'form': form})

Template for Registration (register.html)

html

{% extends "myapp/base.html" %}

{% block content %}
    <h2>Sign Up</h2>
    <form method="POST">
        {% csrf_token %} <!-- Crucial for security in all Django forms -->
        
        <!-- Render the form fields as paragraphs -->
        {{ form.as_p }}
        
        <button type="submit">Sign Up</button>
    </form>
    <p>Already have an account? <a href="{% url 'login' %}">Log In here</a>.</p>
{% endblock %}

2. User Log In

This is where we use the core authenticate() and login() functions.

  • authenticate(request, username=None, password=None): Verifies the username and password. It returns a User object if the credentials are correct, or None if not.

  • login(request, user): Attaches the authenticated User object to the current session, effectively logging the user in.

However, you rarely need to write this yourself! Django provides a ready-to-use view. You just need to hook up the URL and create a template.

URLs (urls.py)

python

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views # Import the built-in auth views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', auth_views.LoginView.as_view(template_name='myapp/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='myapp/logout.html'), name='logout'),
    path('', include('myapp.urls')),
]

Template for Login (login.html)

html

{% extends "myapp/base.html" %}

{% block content %}
    <h2>Log In</h2>
    
    <!-- Display form errors if they exist -->
    {% if form.errors %}
        <p>Your username and password didn't match. Please try again.</p>
    {% endif %}

    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Log In</button>
    </form>
    <p>Don't have an account? <a href="{% url 'register' %}">Sign Up here</a>.</p>
{% endblock %}

3. User Log Out

The process is simple and handled by the logout() function, which flushes the user's session.

Again, we use the built-in view (LogoutView) from the URLs above.

Template for Logout (logout.html)

html

{% extends "myapp/base.html" %}

{% block content %}
    <h2>You have been logged out</h2>
    <div>
        <a href="{% url 'login' %}">Log In Again</a>
    </div>
{% endblock %}

4. Authorization: Protecting Views with @login_required

Once a user is logged in, you often want to restrict access to certain pages. The @login_required decorator is the simplest way to do this.

python

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

@login_required # This is the key!
def profile(request):
    # This view will only run if the user is logged in.
    # If not, it will redirect them to the login page.
    return render(request, 'myapp/profile.html')

What happens when an anonymous user visits a @login_required page?

  1. They are redirected to the login page (/login/ by default).

  2. After a successful login, they are automatically sent back to the page they originally tried to access.

5. Accessing User Information in Templates

The authenticated user is automatically available in every template via the {{ user }} variable.

html

<!-- base.html or any template -->
<div>
    {% if user.is_authenticated %}
        <!-- User is logged in -->
        <p>Hello, <strong>{{ user.username }}</strong>!</p>
        <a href="{% url 'profile' %}">Profile</a>
        <form action="{% url 'logout' %}" method="post" style="display: inline;">
            {% csrf_token %}
            <button type="submit">Logout</button>
        </form>
    {% else %}
        <!-- User is not logged in -->
        <a href="{% url 'login' %}">Login</a> |
        <a href="{% url 'register' %}">Register</a>
    {% endif %}
</div>

Summary

Concept What it is / How to use it Purpose
User Model from django.contrib.auth.models import User The database table that stores user info.
UserCreationForm A built-in form for user registration. Handles the logic and validation for creating a new user.
authenticate() user = authenticate(username, password) Verifies user credentials. Returns a User object or None.
login() login(request, user) Attaches a user to the current session, logging them in.
logout() logout(request) Removes the user from the session, logging them out.
@login_required A decorator placed above a view function. Restricts access to a view to logged-in users only.
{{ user }} The template variable for the current user. Check login status (is_authenticated) and display user info.

The Complete Flow:

  1. Sign Up: Use UserCreationForm in a view to create a new User.

  2. Log In: Use the built-in LoginView which internally uses authenticate() and login().

  3. Access Control: Use @login_required to protect sensitive views.

  4. User Feedback: Use {{ user }} in templates to personalize the experience.

  5. Log Out: Use the built-in LogoutView which internally uses logout().

Comments (0)

No comments yet. Be the first to comment!

LecturreAI Assistant

Hello! I'm LecturreAI

What would you like to learn today?