--- name: auth-system-builder description: Genera sistema completo de autenticación para Django con registro, login, verificación de email, recuperación de contraseña, social auth y protección de vistas. Usa django-allauth y best practices de seguridad. --- # Auth System Builder - Django ## Propósito Este skill genera sistemas de autenticación completos para Django que puedes implementar en 15 minutos. Incluye todo el código necesario: registro, login, verificación de email, recuperación de contraseña, social authentication (Google, GitHub) y protección de vistas. ## Stack Tecnológico **Framework:** Django 4.x / 5.x **Paquetes principales:** - `django-allauth` (auth social + email verification) - `django-crispy-forms` (formularios bonitos) - `crispy-bootstrap5` (estilos Bootstrap 5) **Base de datos:** PostgreSQL / SQLite (desarrollo) ## Cuándo Usar Este Skill ✅ Agregar autenticación completa a proyecto Django nuevo ✅ Registro con verificación de email obligatoria ✅ Login con email o username ✅ Recuperación de contraseña por email ✅ Social login (Google, GitHub, Facebook) ✅ Protección de vistas con decoradores ✅ User profile extendido --- ## Instalación Rápida (15 minutos) ### 1. Instalar Dependencias ```bash pip install django-allauth django-crispy-forms crispy-bootstrap5 pip freeze > requirements.txt ``` ### 2. Configurar `settings.py` ```python # settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', # REQUERIDO por allauth # Apps de terceros 'allauth', 'allauth.account', 'allauth.socialaccount', 'allauth.socialaccount.providers.google', # OAuth Google 'allauth.socialaccount.providers.github', # OAuth GitHub 'crispy_forms', 'crispy_bootstrap5', # Tus apps # 'miapp', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'allauth.account.middleware.AccountMiddleware', # AGREGAR ESTO ] # Site ID requerido por django-allauth SITE_ID = 1 # Authentication backends AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', 'allauth.account.auth_backends.AuthenticationBackend', ] # Configuración de django-allauth ACCOUNT_AUTHENTICATION_METHOD = 'email' # Login con email ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_EMAIL_VERIFICATION = 'mandatory' # Obligatorio verificar email ACCOUNT_USERNAME_REQUIRED = False # No requerir username ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE = True # Confirmar email en registro ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 5 ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 300 # 5 minutos ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = True ACCOUNT_SESSION_REMEMBER = True # URLs de redirección LOGIN_REDIRECT_URL = '/dashboard/' ACCOUNT_LOGOUT_REDIRECT_URL = '/accounts/login/' LOGIN_URL = '/accounts/login/' # Email backend (desarrollo) EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # Email backend (producción - ejemplo con Gmail) # EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # EMAIL_HOST = 'smtp.gmail.com' # EMAIL_PORT = 587 # EMAIL_USE_TLS = True # EMAIL_HOST_USER = 'tu-email@gmail.com' # EMAIL_HOST_PASSWORD = 'tu-app-password' # DEFAULT_FROM_EMAIL = 'tu-email@gmail.com' # Crispy Forms CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" CRISPY_TEMPLATE_PACK = "bootstrap5" # Seguridad (producción) # SESSION_COOKIE_SECURE = True # CSRF_COOKIE_SECURE = True # SECURE_SSL_REDIRECT = True ``` ### 3. Configurar URLs principales ```python # proyecto/urls.py from django.contrib import admin from django.urls import path, include from django.views.generic import TemplateView urlpatterns = [ path('admin/', admin.site.urls), path('accounts/', include('allauth.urls')), # Todas las URLs de auth path('', TemplateView.as_view(template_name='home.html'), name='home'), path('dashboard/', TemplateView.as_view(template_name='dashboard.html'), name='dashboard'), ] ``` ### 4. Migrar Base de Datos ```bash python manage.py migrate python manage.py createsuperuser ``` ### 5. Crear Site en Admin ```bash python manage.py shell ``` ```python from django.contrib.sites.models import Site site = Site.objects.get(id=1) site.domain = 'localhost:8000' # o tu dominio site.name = 'Mi Sitio' site.save() ``` --- ## Templates Base ### Base Template **Archivo:** `templates/base.html` ```html {% block title %}Mi Sitio{% endblock %}
{% if messages %} {% for message in messages %} {% endfor %} {% endif %} {% block content %}{% endblock %}
``` ### Home Page **Archivo:** `templates/home.html` ```html {% extends 'base.html' %} {% block content %}

Bienvenido

Sistema de autenticación completo con Django

{% if not user.is_authenticated %}
Crear Cuenta Iniciar Sesión
{% else %}
Ir al Dashboard
{% endif %}
{% endblock %} ``` ### Dashboard (Protegido) **Archivo:** `templates/dashboard.html` ```html {% extends 'base.html' %} {% block title %}Dashboard{% endblock %} {% block content %}

Dashboard

Información del Usuario
Email:
{{ user.email }}
Usuario:
{{ user.username|default:"No configurado" }}
Email verificado:
{% if user.emailaddress_set.first.verified %} {% else %} No {% endif %}
Fecha de registro:
{{ user.date_joined|date:"d/m/Y H:i" }}
{% endblock %} ``` --- ## Personalizar Templates de django-allauth Crea carpeta `templates/account/` y sobrescribe templates: ### Login Personalizado **Archivo:** `templates/account/login.html` ```html {% extends 'base.html' %} {% load crispy_forms_tags %} {% block title %}Iniciar Sesión{% endblock %} {% block content %}

Iniciar Sesión

{% csrf_token %} {{ form|crispy }}

O inicia sesión con:

¿No tienes cuenta? Regístrate aquí

{% endblock %} ``` ### Registro Personalizado **Archivo:** `templates/account/signup.html` ```html {% extends 'base.html' %} {% load crispy_forms_tags %} {% block title %}Registro{% endblock %} {% block content %}

Crear Cuenta

{% csrf_token %} {{ form|crispy }}

O regístrate con:

¿Ya tienes cuenta? Inicia sesión aquí

{% endblock %} ``` --- ## Protección de Vistas ### Con Decorador (Function-Based Views) ```python from django.contrib.auth.decorators import login_required from django.shortcuts import render @login_required def dashboard_view(request): return render(request, 'dashboard.html') ``` ### Con Mixin (Class-Based Views) ```python from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import TemplateView class DashboardView(LoginRequiredMixin, TemplateView): template_name = 'dashboard.html' login_url = '/accounts/login/' ``` --- ## Modelo de Usuario Extendido Si necesitas campos adicionales en el usuario: ```python # miapp/models.py from django.contrib.auth.models import User from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') phone = models.CharField(max_length=20, blank=True) bio = models.TextField(max_length=500, blank=True) birth_date = models.DateField(null=True, blank=True) avatar = models.ImageField(upload_to='avatars/', null=True, blank=True) def __str__(self): return f'Perfil de {self.user.email}' # Crear Profile automáticamente al crear User @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.profile.save() ``` ```bash python manage.py makemigrations python manage.py migrate ``` --- ## Configurar OAuth (Google) ### 1. Crear proyecto en Google Cloud Console 1. Ve a https://console.cloud.google.com 2. Crea nuevo proyecto 3. Habilita "Google+ API" 4. Ve a "Credentials" > "Create Credentials" > "OAuth 2.0 Client ID" 5. Tipo: Web application 6. Authorized redirect URIs: - `http://localhost:8000/accounts/google/login/callback/` - `https://tudominio.com/accounts/google/login/callback/` ### 2. Configurar en Django Admin 1. Inicia sesión en `/admin/` 2. Ve a "Social applications" > "Add social application" 3. Provider: Google 4. Name: Google OAuth 5. Client ID: [tu client id] 6. Secret key: [tu client secret] 7. Sites: Selecciona tu site 8. Save --- ## Email Templates Personalizados **Archivo:** `templates/account/email/email_confirmation_subject.txt` ``` Confirma tu email en {{ site_name }} ``` **Archivo:** `templates/account/email/email_confirmation_message.txt` ``` Hola {{ user.email }}, Gracias por registrarte en {{ site_name }}. Para completar tu registro, por favor confirma tu dirección de email haciendo click en el siguiente enlace: {{ activate_url }} Este enlace expira en {{ expiration_days }} días. Saludos, El equipo de {{ site_name }} ``` --- ## Configuración de Email en Producción ### Con Gmail (menos seguro) ```python # settings.py EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = 'tu-email@gmail.com' EMAIL_HOST_PASSWORD = 'tu-app-password' # Generar en Google Account DEFAULT_FROM_EMAIL = 'tu-email@gmail.com' ``` ### Con SendGrid (recomendado) ```bash pip install sendgrid ``` ```python # settings.py EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.sendgrid.net' EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = 'apikey' EMAIL_HOST_PASSWORD = 'tu-api-key-de-sendgrid' DEFAULT_FROM_EMAIL = 'noreply@tudominio.com' ``` --- ## Checklist de Implementación - [ ] Instalar django-allauth y crispy-forms - [ ] Configurar INSTALLED_APPS - [ ] Configurar AUTHENTICATION_BACKENDS - [ ] Configurar account settings en settings.py - [ ] Configurar URLs principales - [ ] Ejecutar migraciones - [ ] Crear Site en admin - [ ] Crear templates base - [ ] Personalizar templates de login/signup - [ ] Configurar email backend - [ ] Probar registro + verificación de email - [ ] Probar login/logout - [ ] Probar recuperación de contraseña - [ ] Configurar OAuth providers (opcional) - [ ] Implementar Profile model (opcional) --- ## Comandos Útiles ```bash # Verificar configuración de email python manage.py shell from django.core.mail import send_mail send_mail('Test', 'Mensaje', 'from@example.com', ['to@example.com']) # Limpiar sesiones expiradas python manage.py clearsessions # Crear usuario de prueba python manage.py shell from django.contrib.auth.models import User User.objects.create_user('test@example.com', 'test@example.com', 'password123') ``` --- ## Troubleshooting **Error: "Site matching query does not exist"** ```python python manage.py shell from django.contrib.sites.models import Site Site.objects.create(domain='localhost:8000', name='Dev Site') ``` **Email no llega en desarrollo:** - Verifica `EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'` - El email se imprime en la consola, no se envía realmente **OAuth redirect mismatch:** - Verifica que las URLs en Google Console coincidan exactamente - Incluye http:// o https:// - No olvides la barra final / --- ## Formato de Output Cuando uses este skill, especifica: - Si necesitas OAuth (Google, GitHub, etc.) - Si necesitas Profile extendido - Si necesitas email templates personalizados Ejemplo: ``` "Implementa autenticación completa con django-allauth. Necesito registro con verificación de email, OAuth con Google, y un modelo Profile con teléfono y avatar." ``` El skill generará todo el código necesario listo para implementar.