Skip to content

Autenticacion

Technomantus Corvi edited this page Sep 5, 2026 · 1 revision

Autenticación (tanuki_login)

Un sistema completo de autenticación basado en sesión — login, logout, registro y recuperación de contraseña por email. Vive en el repo desde el principio pero permanece inerte: ninguna ruta se registra por defecto, así que no tiene coste hasta que descomentas sus rutas en routes.php.

Qué incluye

Pieza Archivo
Envío de correo (SMTP) config/mail.phpMail::send($to, $subject, $html)
Helpers de sesión/auth auth.phpauth_check(), auth_user(), auth_login(), auth_logout(), auth_require()
Modelo de usuario models/UserModel.php
Tokens de recuperación models/PasswordResetModel.php
Controlador controllers/AuthController.php
Edición de perfil controllers/ProfileController.php
Vistas views/auth/*.php, views/profile/edit.php

Configuración

1. Instalar PHPMailer

composer require phpmailer/phpmailer

2. Crear las tablas (MySQL/MariaDB mostrado; ver comentarios SQL para tipos de PostgreSQL):

CREATE TABLE users (
    id            INT AUTO_INCREMENT PRIMARY KEY,
    name          VARCHAR(255) NOT NULL,
    email         VARCHAR(255) NOT NULL UNIQUE,
    password      VARCHAR(255) NOT NULL,
    created_at    TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at    TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

CREATE TABLE password_resets (
    id            INT AUTO_INCREMENT PRIMARY KEY,
    email         VARCHAR(255) NOT NULL,
    token         VARCHAR(255) NOT NULL,
    expires_at    TIMESTAMP NOT NULL,
    created_at    TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Si registras las rutas sin estas tablas, verás un 500 claro (o la excepción completa en modo debug) en cuanto una query toque users — es la señal esperada de que faltó este paso.

3. Conéctalo al bootstrap (core/App.php, junto a los demás requires de config/):

require_once __DIR__ . '/../config/mail.php';
require_once __DIR__ . '/../auth.php';

4. Configura SMTP en .env:

MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=no-reply@example.com
MAIL_FROM_NAME="${APP_NAME}"

5. Descomenta las rutas en routes.php:

'GET  /login'                   => 'AuthController@showLogin',
'POST /login'                   => 'AuthController@login',
'POST /logout'                  => 'AuthController@logout',
'GET  /register'                => 'AuthController@showRegister',
'POST /register'                => 'AuthController@register',
'GET  /forgot-password'         => 'AuthController@showForgot',
'POST /forgot-password'         => 'AuthController@sendResetLink',
'GET  /reset-password/{token}'  => 'AuthController@showReset',
'POST /reset-password/{token}'  => 'AuthController@resetPassword',
'GET  /profile'                 => 'ProfileController@edit',
'POST /profile'                 => 'ProfileController@update',

Proteger una ruta

class DashboardController extends Controller
{
    public function index(): void
    {
        auth_require(); // redirige a /login si no hay sesión
        $user = auth_user();
        $this->view('dashboard/index', ['user' => $user]);
    }
}

auth_require() guarda la URL actual antes de redirigir, así que el login devuelve al usuario a donde quería ir.

El menú de usuario en el nav

includes/head.php ya renderiza un dropdown de usuario (avatar, enlace a perfil, logout) cuando auth_check() es verdadero, y un botón "Iniciar sesión" en caso contrario — sin cableado adicional una vez activas las rutas.

Flujo de recuperación de contraseña

  1. El usuario envía su email en /forgot-password.
  2. Se genera un token aleatorio, se hashea con SHA-256, se guarda con expiración de 1 hora. El token en texto plano es el que se envía por email (no el hash) — práctica estándar, así una tabla filtrada por sí sola no sirve para restablecer cuentas.
  3. Se muestra el mismo mensaje de "enlace enviado" exista o no el email, para no filtrar qué emails están registrados.
  4. /reset-password/{token} valida el token antes de permitir una nueva contraseña.

Editar el perfil

/profile permite a un usuario logueado cambiar su nombre y, opcionalmente, su contraseña (pide la contraseña actual) — no su email, a propósito, para mantener esto simple. Los cambios de email normalmente necesitan su propio flujo de re-verificación.

Eliminar la extensión

Quita las dos líneas require_once de App.php, comenta/borra las rutas en routes.php, y (opcionalmente) borra los archivos listados arriba. Nada más en el proyecto depende de ellos.

Clone this wiki locally