MVC Master

Módulo 3: El Guardián (Login y Seguridad)

La fase cero del negocio real: Nadie maneja la Universidad sin credenciales. Haremos que MySQL evalúe encriptación Bcrypt, daremos la vista Front-End HTML pura, y asignaremos Middlewares interceptores.

1. El Modelo de Usuarios (Quien entra)

app/Models/UsuarioModelo.php
<?php
namespace App\Models;

class UsuarioModelo extends \App\Core\ModeloBase {
    protected $tabla = 'usuarios';
    
    // Método crítico para buscar el email sin contraseñas
    public function buscarPorCorreo($correo) {
        $stmt = $this->db->prepare("SELECT * FROM {$this->tabla} WHERE correo = :c LIMIT 1");
        $stmt->execute(['c' => $correo]);
        return $stmt->fetch(\PDO::FETCH_OBJ);
    }
}

2. El Controlador de Auth Segura

app/Controllers/AuthController.php
<?php
namespace App\Controllers;
use App\Models\UsuarioModelo;

class AuthController {
    
    // Carga la Vista FrontHTML
    public function loginView() {
        $view = 'auth/login'; $titulo = "Login de Acceso";
        require_once 'app/Views/layout/main.php';
    }

    // Procesa el Email del Invasor
    public function autenticar() {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $modelo = new UsuarioModelo();
            $usuario = $modelo->buscarPorCorreo($_POST['correo']);

            // Mide tu tipeo textoplano vs la Encriptación DB
            if ($usuario && password_verify($_POST['password'], $usuario->password)) {
                // EXITO: Inicia Sesiones RAM Global
                $_SESSION['usuario_rol'] = $usuario->rol;
                $_SESSION['usuario_nombre'] = $usuario->nombre;
                
                header("Location: /dashboard/estudiantes");
                exit;
            } else {
                header("Location: /login?err=Credenciales Equivocadas!");
                exit;
            }
        }
    }

    public function logout() {
        session_destroy();
        header("Location: /login");
    }
}

3. HTML del Formulario (Vista Integral)

app/Views/auth/login.php
<div class="container d-flex justify-content-center mt-5">
    <div class="card shadow border-0 p-4" style="width: 400px; border-radius:15px;">
        <h3 class="text-center text-primary fw-bold mb-4"><i class="bi bi-shield-lock-fill"></i> ZONA RESTRINGIDA</h3>
        
        <!-- Alert SweetAlert Inyector (Para errores GET[err]) -->
        <?php if(isset($_GET['err'])): ?>
            <div class="alert alert-danger"><?= htmlspecialchars($_GET['err']) ?></div>
        <?php endif; ?>

        <!-- Conexión CRITICA al Enrutador /login -->
        <form action="/login_autenticar" method="POST">
            <div class="mb-3">
                <label class="fw-bold text-muted">Correo Directorio</label>
                <input type="email" name="correo" class="form-control" placeholder="admin@admin.com" required>
            </div>
            
            <div class="mb-4">
                <label class="fw-bold text-muted">Clave Secreta</label>
                <input type="password" name="password" class="form-control" required>
            </div>

            <button type="submit" class="btn btn-dark w-100 fw-bold py-2">ENTRAR AL PANEL</button>
        </form>
    </div>
</div>