Lección 29 de 45 15 min de lectura

Laravel Breeze

Laravel Breeze es el starter kit oficial más sencillo para añadir autenticación a tu aplicación. Proporciona registro, login, recuperación de contraseña y verificación de email con código limpio y fácil de personalizar.

¿Qué es Laravel Breeze?

Breeze es un paquete oficial de Laravel que genera toda la infraestructura de autenticación: controladores, vistas, rutas y tests. A diferencia de otros sistemas más complejos, Breeze:

  • Genera código directamente en tu proyecto (no es una dependencia oculta)
  • Usa Blade puro con Tailwind CSS (también hay opciones con Vue, React o Livewire)
  • Es fácil de entender y modificar
  • Incluye tests funcionales

Instalación de Breeze

Primero, instala el paquete vía Composer. Es una dependencia de desarrollo porque solo la usas para generar el código:

bash
composer require laravel/breeze --dev

Luego, ejecuta el comando de instalación. Breeze te preguntará qué stack quieres usar:

bash
php artisan breeze:install

Te mostrará un menú interactivo con las opciones disponibles:

text
 Which Breeze stack would you like to install?
  Blade with Alpine ........................ blade
  Livewire (Volt Class API) with Alpine .... livewire
  Livewire (Volt Functional API) with Alpine livewire-functional
  React with Inertia ....................... react
  Vue with Inertia ......................... vue
  API only ................................. api

Para este curso, selecciona blade. Es la opción más sencilla y usa lo que ya conoces: plantillas Blade con Alpine.js para interactividad ligera.

Después te preguntará si quieres modo oscuro y qué framework de testing prefieres (Pest o PHPUnit). Puedes aceptar los valores por defecto.

Pasos finales de instalación

Una vez instalado Breeze, ejecuta las migraciones y compila los assets:

bash
# Ejecutar migraciones
php artisan migrate

# Instalar dependencias de Node
npm install

# Compilar assets (desarrollo)
npm run dev

Ahora tu aplicación tiene un sistema de autenticación completo. Inicia el servidor y pruébalo:

bash
php artisan serve

Visita http://localhost:8000 y verás enlaces para "Log in" y "Register" en la esquina superior derecha.

¿Qué archivos genera Breeze?

Breeze genera código directamente en tu proyecto. Esto te da control total para personalizarlo. Los archivos principales son:

Controladores

En app/Http/Controllers/Auth/ encontrarás:

  • AuthenticatedSessionController - Login y logout
  • RegisteredUserController - Registro de usuarios
  • PasswordResetLinkController - Solicitar reset de contraseña
  • NewPasswordController - Establecer nueva contraseña
  • EmailVerificationPromptController - Verificación de email
  • ConfirmablePasswordController - Confirmar contraseña

Vistas

En resources/views/auth/ están las plantillas Blade:

  • login.blade.php - Formulario de login
  • register.blade.php - Formulario de registro
  • forgot-password.blade.php - Solicitar reset
  • reset-password.blade.php - Nueva contraseña
  • verify-email.blade.php - Verificar email
  • confirm-password.blade.php - Confirmar contraseña

Rutas

Breeze añade un archivo routes/auth.php con todas las rutas de autenticación, que se incluye desde routes/web.php.

Rutas de autenticación

Puedes ver todas las rutas de auth ejecutando:

bash
php artisan route:list --path=auth

Las rutas principales que Breeze crea son:

  • GET /register - Formulario de registro (nombre: register)
  • POST /register - Procesar registro
  • GET /login - Formulario de login (nombre: login)
  • POST /login - Procesar login
  • POST /logout - Cerrar sesión (nombre: logout)
  • GET /forgot-password - Solicitar reset (nombre: password.request)
  • POST /forgot-password - Enviar email de reset
  • GET /reset-password/{token} - Formulario nueva contraseña
  • POST /reset-password - Guardar nueva contraseña

El Dashboard

Breeze crea una ruta /dashboard protegida que solo pueden ver usuarios autenticados. Está en routes/web.php:

php
<?php

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');

Los middlewares auth y verified aseguran que solo usuarios autenticados y con email verificado puedan acceder. Veremos más sobre proteger rutas en la siguiente lección.

Cómo funciona el registro

Veamos el controlador de registro para entender el flujo:

php
<?php

// app/Http/Controllers/Auth/RegisteredUserController.php

declare(strict_types=1);

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;
use Illuminate\View\View;

class RegisteredUserController extends Controller
{
    // Mostrar formulario de registro
    public function create(): View
    {
        return view('auth.register');
    }

    // Procesar el registro
    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        event(new Registered($user));

        Auth::login($user);

        return redirect(route('dashboard', absolute: false));
    }
}

El flujo es:

  1. Valida los datos del formulario
  2. Crea el usuario con la contraseña hasheada
  3. Dispara el evento Registered (para enviar email de verificación)
  4. Autentica al usuario automáticamente
  5. Redirige al dashboard

Cómo funciona el login

El controlador de sesión maneja el login:

php
<?php

// app/Http/Controllers/Auth/AuthenticatedSessionController.php

declare(strict_types=1);

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

class AuthenticatedSessionController extends Controller
{
    // Mostrar formulario de login
    public function create(): View
    {
        return view('auth.login');
    }

    // Procesar login
    public function store(LoginRequest $request): RedirectResponse
    {
        $request->authenticate();

        $request->session()->regenerate();

        return redirect()->intended(route('dashboard', absolute: false));
    }

    // Cerrar sesión
    public function destroy(Request $request): RedirectResponse
    {
        Auth::guard('web')->logout();

        $request->session()->invalidate();

        $request->session()->regenerateToken();

        return redirect('/');
    }
}

Observa que usa un LoginRequest personalizado que está en app/Http/Requests/Auth/LoginRequest.php. Este Form Request contiene la lógica de autenticación y protección contra ataques de fuerza bruta (rate limiting).

Personalizar las vistas

Las vistas de Breeze usan Tailwind CSS y están diseñadas para ser fáciles de modificar. Por ejemplo, para cambiar el formulario de login:

blade
{{-- resources/views/auth/login.blade.php --}}

<x-guest-layout>
    <!-- Estado de sesión -->
    <x-auth-session-status class="mb-4" :status="session('status')" />

    <form method="POST" action="{{ route('login') }}">
        @csrf

        <!-- Email -->
        <div>
            <x-input-label for="email" :value="__('Email')" />
            <x-text-input
                id="email"
                class="block mt-1 w-full"
                type="email"
                name="email"
                :value="old('email')"
                required
                autofocus
                autocomplete="username"
            />
            <x-input-error :messages="$errors->get('email')" class="mt-2" />
        </div>

        <!-- Contraseña -->
        <div class="mt-4">
            <x-input-label for="password" :value="__('Password')" />
            <x-text-input
                id="password"
                class="block mt-1 w-full"
                type="password"
                name="password"
                required
                autocomplete="current-password"
            />
            <x-input-error :messages="$errors->get('password')" class="mt-2" />
        </div>

        <!-- Recuérdame -->
        <div class="block mt-4">
            <label for="remember_me" class="inline-flex items-center">
                <input
                    id="remember_me"
                    type="checkbox"
                    name="remember"
                    class="rounded border-gray-300"
                >
                <span class="ms-2 text-sm text-gray-600">
                    {{ __('Remember me') }}
                </span>
            </label>
        </div>

        <div class="flex items-center justify-end mt-4">
            @if (Route::has('password.request'))
                <a
                    class="underline text-sm text-gray-600 hover:text-gray-900"
                    href="{{ route('password.request') }}"
                >
                    {{ __('Forgot your password?') }}
                </a>
            @endif

            <x-primary-button class="ms-3">
                {{ __('Log in') }}
            </x-primary-button>
        </div>
    </form>
</x-guest-layout>

Breeze usa componentes Blade personalizados como x-text-input, x-input-label y x-primary-button. Estos están en resources/views/components/ y puedes modificarlos.

Traducir al español

Por defecto, Breeze usa el helper __() para las cadenas de texto, lo que facilita la traducción. Para traducir al español:

  1. Cambia el locale en el archivo .env:
env
APP_LOCALE=es
  1. Crea el archivo de traducciones lang/es.json:
json
{
    "Email": "Correo electrónico",
    "Password": "Contraseña",
    "Remember me": "Recuérdame",
    "Forgot your password?": "¿Olvidaste tu contraseña?",
    "Log in": "Iniciar sesión",
    "Register": "Registrarse",
    "Name": "Nombre",
    "Confirm Password": "Confirmar contraseña",
    "Already registered?": "¿Ya tienes cuenta?",
    "Dashboard": "Panel",
    "Profile": "Perfil",
    "Log Out": "Cerrar sesión"
}

Verificación de email

Breeze incluye verificación de email. Para activarla, asegúrate de que tu modelo User implemente MustVerifyEmail:

php
<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    // ...
}

También necesitas configurar el envío de emails en tu archivo .env. Para desarrollo, puedes usar el driver log que escribe los emails en storage/logs/laravel.log:

env
MAIL_MAILER=log

Perfil de usuario

Breeze incluye una página de perfil donde el usuario puede actualizar su nombre, email y contraseña, o eliminar su cuenta. Está en /profile y usa el controlador ProfileController.

php
<?php

// routes/web.php

Route::middleware('auth')->group(function () {
    Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});

Comparación con otros starter kits

Laravel ofrece varias opciones. Aquí te ayudo a elegir:

  • Breeze: Simple, código visible, ideal para aprender y proyectos pequeños/medianos
  • Jetstream: Más completo (equipos, 2FA, API tokens), usa Livewire o Inertia
  • Fortify: Solo backend, sin vistas. Útil si quieres crear tu propio frontend

Para la mayoría de proyectos, Breeze es la mejor opción para empezar. Si más adelante necesitas funcionalidades avanzadas, puedes añadirlas manualmente o migrar a Jetstream.

Resumen

  • Laravel Breeze es el starter kit más sencillo para autenticación
  • Se instala con composer require laravel/breeze --dev y php artisan breeze:install
  • Genera controladores, vistas, rutas y tests directamente en tu proyecto
  • Incluye: registro, login, logout, reset de contraseña, verificación de email y perfil
  • Usa Blade con Tailwind CSS (también hay opciones con Vue, React o Livewire)
  • El código es tuyo: puedes personalizarlo completamente
  • Para traducir, usa archivos JSON en lang/es.json

Ejercicios

Ejercicio 1: Instalar Breeze en un proyecto nuevo

Crea un nuevo proyecto Laravel y añade Breeze con el stack Blade. Ejecuta las migraciones, compila los assets y prueba el registro y login de usuarios.

Ver solución
# Crear proyecto nuevo
composer create-project laravel/laravel mi-app-auth
cd mi-app-auth

# Instalar Breeze
composer require laravel/breeze --dev

# Ejecutar instalación (seleccionar "blade")
php artisan breeze:install

# Ejecutar migraciones
php artisan migrate

# Instalar dependencias Node y compilar
npm install
npm run dev

# En otra terminal, iniciar servidor
php artisan serve

# Visitar http://localhost:8000
# Click en "Register" para crear una cuenta
# Luego probar "Log in" con esas credenciales

Ejercicio 2: Traducir Breeze al español

Configura tu aplicación para usar español como idioma por defecto. Crea el archivo de traducciones con al menos las cadenas del formulario de login: Email, Password, Remember me, Forgot your password?, y Log in.

Ver solución
# .env
APP_LOCALE=es
// lang/es.json (crear este archivo)
{
    "Email": "Correo electrónico",
    "Password": "Contraseña",
    "Remember me": "Recuérdame",
    "Forgot your password?": "¿Olvidaste tu contraseña?",
    "Log in": "Iniciar sesión",
    "Register": "Registrarse",
    "Name": "Nombre",
    "Confirm Password": "Confirmar contraseña",
    "Already registered?": "¿Ya tienes cuenta?",
    "Dashboard": "Panel de control",
    "Log Out": "Cerrar sesión"
}

Ejercicio 3: Activar verificación de email

Modifica el modelo User para que requiera verificación de email. Configura el driver de mail como "log" y registra un usuario nuevo. Busca el enlace de verificación en el archivo de log.

Ver solución
<?php

// app/Models/User.php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    // resto del código...
}
# .env
MAIL_MAILER=log
# Después de registrar un usuario, buscar el enlace:
cat storage/logs/laravel.log | grep "verify"

# Verás algo como:
# http://localhost:8000/email/verify/1/abc123...

¿Te está gustando el curso?

Tenemos cursos premium con proyectos reales, soporte personalizado y certificado.

Descubrir cursos premium