Sistema de usuario — Registro, inicio de sesión, cierre de sesión

En este capítulo aprenderás a usar el sistema de autenticación incorporado de Django para implementar las funciones de registro, inicio de sesión y cierre de sesión de usuario.


El sistema auth incorporado de Django

Django incluye un módulo completo de autenticación de usuarios:

  • IncorporadoUserModelos (nombre de usuario, contraseña, correo electrónico, etc.)
  • Vistas integradas de inicio/cierre de sesión (no necesitas escribir la lógica tú mismo)
  • Gestión integrada de permisos y grupos
  • Validación de formularios y protección de seguridad (CSRF, XSS)

Este módulo esdjango.contrib.auth, y ya está registrado por defecto en INSTALLED_APPS al crear el proyecto.


Página de registro

Django incluye vistas de inicio y cierre de sesión, pero no incluye una vista de registro integrada; debemos escribirla nosotros.

Paso 1: Crear el formulario de registro

Ejemplo

# Ruta del archivo: blog/forms.py (nuevo archivo)
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

class RegisterForm(UserCreationForm):
    """Formulario de registro personalizado: hereda de UserCreationForm y agrega un campo de correo electrónico"""
    email = forms.EmailField(
        label='Correo electrónico',
        required=True,
        help_text='Introduzca una dirección de correo electrónico válida.'
    )

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']
        labels = {
            'username': 'Nombre de usuario',
        }

Paso 2: Escribir la vista de registro

Ejemplo

# Ruta del archivo: blog/views.py (agregar)
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.contrib import messages
from .forms import RegisterForm

def register(request):
    """Vista de registro de usuario"""
    # Si el usuario ya ha iniciado sesión, redirigir directamente a la página principal
    if request.user.is_authenticated:
        return redirect('index')

    if request.method == 'POST':
        # El usuario envió el formulario de registro
        form = RegisterForm(request.POST)
        if form.is_valid():
            user = form.save()              # Guardar el usuario en la base de datos
            login(request, user)            # Iniciar sesión automáticamente después del registro
            messages.success(request, f'¡Registro exitoso, bienvenido, {user.username}!')
            return redirect('index')
    else:
        # Solicitud GET: mostrar el formulario de registro vacío
        form = RegisterForm()

    return render(request, 'blog/register.html', {
        'form': form,
        'title': 'Registro - Blog EJEMPLO'
    })

El framework de messages de Djangomessagesse utiliza para transmitir mensajes de una sola vez entre solicitudes (como «Registro exitoso»). Al renderizar el área de messages en la plantilla, el usuario puede ver la retroalimentación de la operación. Funciona junto con session; los mensajes desaparecen automáticamente después de mostrarse una vez.


Inicio de sesión y cierre de sesión

Django incluye vistas de inicio y cierre de sesión; solo hay que importarlas en las rutas.

Ejemplo

# Ruta del archivo: blog/urls.py
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
    path('register/', views.register, name='register'),

    # Vista de inicio de sesión incorporada en Django
    # template_name: especifica qué plantilla usar
    path('login/', auth_views.LoginView.as_view(
        template_name='blog/login.html',
        redirect_authenticated_user=True  # Si un usuario ya ha iniciado sesión y accede a login, redirigir directamente
    ), name='login'),

    # Vista de cierre de sesión incorporada en Django
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]

En settings.py, configura las direcciones de redirección para inicio/cierre de sesión:

Ejemplo

# Ruta del archivo: blog_project/settings.py (agregar al final)
LOGIN_URL = 'login'                    # Cuando un usuario no autenticado accede a una página protegida, redirigir a la página de inicio de sesión
LOGIN_REDIRECT_URL = 'index'           # Después de iniciar sesión correctamente, redirigir a la página principal
LOGOUT_REDIRECT_URL = 'index'          # Después de cerrar sesión, redirigir a la página principal

Crear plantillas de autenticación

Plantilla de inicio de sesión

Ejemplo

<!-- Ruta del archivo: blog/templates/blog/login.html -->
{% extends 'blog/base.html' %}

{% block title %}Iniciar sesión - Blog EJEMPLO{% endblock %}

{% block content %}
<div class="auth-form">
    <h2>Iniciar sesión</h2>
    <form method="post">
        {% csrf_token %}
        <div class="form-group">
            <label>Nombre de usuario</label>
            {{ form.username }}
        </div>
        <div class="form-group">
            <label>Contraseña</label>
            {{ form.password }}
        </div>
        {% if form.errors %}
            <p class="error-msg">Nombre de usuario o contraseña incorrectos, inténtalo de nuevo.</p>
        {% endif %}
        <button type="submit" class="btn-submit">Iniciar sesión</button>
    </form>
    <p class="form-footer">
¿Aún no tienes una cuenta?<a href="{% url 'register' %}">Regístrate ahora</a>
    </p>
</div>
{% endblock %}

Plantilla de registro

Ejemplo

<!-- Ruta del archivo: blog/templates/blog/register.html -->
{% extends 'blog/base.html' %}

{% block title %}Registro - Blog EJEMPLO{% endblock %}

{% block content %}
<div class="auth-form">
    <h2>Registro</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn-submit">Registrar</button>
    </form>
    <p class="form-footer">
¿Ya tienes una cuenta?<a href="{% url 'login' %}">Inicia sesión ahora</a>
    </p>
</div>
{% endblock %}

{% csrf_token %}Es el mecanismo de seguridad de Django que previene ataques de falsificación de solicitudes entre sitios. Cualquier formulario POST debe incluirlo; de lo contrario, Django rechazará la solicitud (error 403). Esta etiqueta genera un input oculto que contiene un token CSRF aleatorio.


Mostrar el estado de inicio de sesión en la barra de navegación

Actualiza la barra de navegación de base.html para mostrar contenido diferente según el estado de inicio de sesión.

Ejemplo

<!-- Modificar la sección de la barra de navegación de blog/templates/blog/base.html -->
<header class="navbar">
    <a href="/" class="logo">Blog EJEMPLO</a>
    <nav>
        <a href="/">Inicio</a>

        {% if user.is_authenticated %}
{# Autenticado: mostrar nombre de usuario y botón de cerrar sesión (user se inyecta automáticamente en Django) #}
            <span class="user-name">{{ user.username }}</span>
            <a href="{% url 'logout' %}">Cerrar sesión</a>
        {% else %}
{# No autenticado: mostrar enlaces de inicio de sesión y registro #}
            <a href="{% url 'login' %}">Iniciar sesión</a>
            <a href="{% url 'register' %}">Registro</a>
        {% endif %}
    </nav>
</header>

Los procesadores de contexto de plantillas de Django inyectan automáticamente{{ user }}`user` en cada plantilla, sin necesidad de pasarlo manualmente en views.py. Puedes usaruser.is_authenticated`user.is_authenticated` para determinar si el usuario ha iniciado sesión.


Estilos de la página de inicio de sesión

Ejemplo

/* Agregar en el elemento style de base.html */
.auth-form {
    max-width: 400px;
    margin: 40px auto;
    padding: 30px;
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}

.auth-form h2 {
    margin-bottom: 24px;
    text-align: center;
}

.auth-form .form-group {
    margin-bottom: 16px;
}

.auth-form label {
    display: block;
    margin-bottom: 6px;
    font-weight: 500;
}

.auth-form input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid #ddd;
    border-radius: 6px;
    font-size: 14px;
}

.btn-submit {
    width: 100%;
    padding: 12px;
    background: #2c3e50;
    color: #fff;
    border: none;
    border-radius: 6px;
    font-size: 16px;
    cursor: pointer;
    margin-top: 10px;
}

.error-msg {
    color: #e74c3c;
    font-size: 14px;
}

.form-footer {
    margin-top: 16px;
    text-align: center;
    font-size: 14px;
}

.user-name {
    color: #2c3e50;
    font-weight: 500;
}

Resumen del capítulo

En este capítulo has integrado el sistema de autenticación incorporado de Django: heredaste UserCreationForm para crear el formulario de registro, usaste LoginView/LogoutView para implementar el inicio y cierre de sesión, usaste csrf_token para proteger las solicitudes POST y usaste user.is_authenticated en las plantillas para determinar el estado de inicio de sesión.

Ahora el blog tiene un flujo completo de registro, inicio de sesión y cierre de sesión de usuarios.

Otras extensiones