laravelautenticacionseguridadroadmap

Autenticación en Laravel: Breeze para web y Sanctum para APIs

La autenticación es una de las primeras cosas que necesitas en cualquier aplicación seria. Laravel ofrece varias soluciones oficiales y cada una está pensada para un caso de uso diferente. En este artículo vamos a ver las dos más usadas: Breeze para aplicaciones web tradicionales y Sanctum para APIs REST.

Panorama de las opciones de autenticación en Laravel

Antes de entrar en materia, conviene saber qué opciones tienes:

  • Laravel Breeze: scaffolding mínimo de autenticación para aplicaciones web. Incluye login, registro, recuperación de contraseña y verificación de email. Usa Blade o puede configurarse con Inertia/Vue/React.
  • Laravel Jetstream: más completo que Breeze, incluye gestión de equipos, autenticación de dos factores, gestión de sesiones, etc.
  • Laravel Sanctum: pensado para autenticación de SPAs y APIs. Usa tokens de API simples o autenticación basada en cookies para SPAs.
  • Laravel Passport: implementación completa de OAuth2 para APIs que necesitan autorización de terceros.

Para la mayoría de proyectos, Breeze + Sanctum cubre todo lo que necesitas.

Laravel Breeze: autenticación para la web

Instalación

Primero, crea un proyecto Laravel limpio o úsalo en uno existente:

composer require laravel/breeze --dev
php artisan breeze:install

Se te preguntará qué stack quieres usar. Para una aplicación tradicional con Blade:

php artisan breeze:install blade

npm install
npm run dev
php artisan migrate

Qué genera Breeze

Después de la instalación, Breeze habrá creado:

  • Rutas: en routes/auth.php (incluido automáticamente desde routes/web.php)
  • Controladores: en app/Http/Controllers/Auth/
  • Vistas: en resources/views/auth/
  • Middleware: EnsureEmailIsVerified

Las rutas que se añaden incluyen login, registro, logout, recuperación de contraseña y verificación de email.

Proteger rutas con el middleware auth

Una vez instalado Breeze, proteger cualquier ruta es tan sencillo como añadir el middleware auth:

// routes/web.php

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

// Grupo de rutas protegidas
Route::middleware(['auth'])->group(function () {
    Route::get('/perfil', [ProfileController::class, 'show'])->name('profile.show');
    Route::put('/perfil', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/perfil', [ProfileController::class, 'destroy'])->name('profile.destroy');
});

Si un usuario no autenticado intenta acceder a estas rutas, Laravel lo redirige automáticamente a /login.

El facade Auth

El facade Auth es tu herramienta principal para trabajar con el usuario autenticado:

use Illuminate\Support\Facades\Auth;

// Obtener el usuario autenticado
$user = Auth::user();
echo $user->name;

// Obtener solo el ID (sin cargar el modelo completo)
$userId = Auth::id();

// Comprobar si hay un usuario autenticado
if (Auth::check()) {
    // El usuario está autenticado
}

// En Blade también tienes acceso directo
// {{ auth()->user()->name }}
// @auth ... @endauth
// @guest ... @endguest

En los controladores puedes usar el helper auth() o tipar la request:

public function store(Request $request): RedirectResponse
{
    $user = $request->user(); // Alternativa a Auth::user()
    // ...
}

Autenticación manual con Auth::attempt()

A veces necesitas autenticar a un usuario de forma programática, por ejemplo en un sistema de login personalizado:

use Illuminate\Support\Facades\Auth;

public function login(Request $request): RedirectResponse
{
    $credentials = $request->validate([
        'email'    => ['required', 'email'],
        'password' => ['required'],
    ]);

    if (Auth::attempt($credentials, $request->boolean('remember'))) {
        $request->session()->regenerate();
        return redirect()->intended('dashboard');
    }

    return back()->withErrors([
        'email' => 'Las credenciales no coinciden con nuestros registros.',
    ])->onlyInput('email');
}

Cerrar sesión

public function logout(Request $request): RedirectResponse
{
    Auth::logout();

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

    return redirect('/');
}

Laravel Sanctum: autenticación para APIs

¿Cuándo usar Sanctum?

Sanctum es la elección correcta cuando construyes:

  • Una API REST consumida por tu propia SPA (Single Page Application)
  • Una API móvil
  • Cualquier API donde los clientes necesiten autenticarse con tokens

Instalación

Sanctum viene incluido en Laravel desde la versión 11, pero si no lo tienes:

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

Configurar el modelo User

Añade el trait HasApiTokens a tu modelo User:

// app/Models/User.php
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    // ...
}

Generar tokens de API

Para crear un token para un usuario, usa el método createToken():

// En el controlador de login de la API
public function login(Request $request): JsonResponse
{
    $request->validate([
        'email'    => 'required|email',
        'password' => 'required',
    ]);

    $user = User::where('email', $request->email)->first();

    if (! $user || ! Hash::check($request->password, $user->password)) {
        return response()->json([
            'message' => 'Credenciales incorrectas.',
        ], 401);
    }

    $token = $user->createToken('auth_token')->plainTextToken;

    return response()->json([
        'access_token' => $token,
        'token_type'   => 'Bearer',
        'user'         => $user,
    ]);
}

Usar el token en las peticiones

El cliente debe enviar el token en el header Authorization:

Authorization: Bearer 1|AbCdEfGhIjKlMnOpQrStUvWxYz1234567890

Con JavaScript/fetch:

const response = await fetch('/api/user', {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Accept': 'application/json',
  }
});

Proteger rutas de la API con Sanctum

// routes/api.php
use Illuminate\Support\Facades\Route;

// Rutas públicas (sin autenticación)
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);

// Rutas protegidas con Sanctum
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });

    Route::apiResource('posts', PostController::class);
    Route::post('/logout', [AuthController::class, 'logout']);
});

Revocar tokens (logout)

public function logout(Request $request): JsonResponse
{
    // Revocar solo el token actual
    $request->user()->currentAccessToken()->delete();

    // O revocar todos los tokens del usuario
    // $request->user()->tokens()->delete();

    return response()->json(['message' => 'Sesión cerrada correctamente.']);
}

Habilidades (abilities) de los tokens

Los tokens de Sanctum pueden tener habilidades específicas, similar a los scopes de OAuth:

// Crear un token con habilidades específicas
$token = $user->createToken('token-admin', ['read:posts', 'create:posts', 'delete:posts'])->plainTextToken;

// O un token de solo lectura
$token = $user->createToken('token-lectura', ['read:posts'])->plainTextToken;

Verificar habilidades en el controlador:

public function destroy(Request $request, Post $post): JsonResponse
{
    if (! $request->user()->tokenCan('delete:posts')) {
        return response()->json(['message' => 'No tienes permiso para esta acción.'], 403);
    }

    $post->delete();

    return response()->json(['message' => 'Publicación eliminada.']);
}

Listar y gestionar tokens

// Ver todos los tokens de un usuario
$tokens = $request->user()->tokens;

// Revocar un token específico por ID
$request->user()->tokens()->where('id', $tokenId)->delete();

Resumen: ¿cuándo usar cada uno?

NecesidadSolución
App web con login/registro clásicoLaravel Breeze
App web con más funcionalidadesLaravel Jetstream
API REST con tokensLaravel Sanctum
OAuth2 / autorizar apps de tercerosLaravel Passport

La combinación más habitual en proyectos modernos es tener Breeze para el panel de administración web y Sanctum para exponer una API que consume un frontend Vue/React o una app móvil.

Conclusión

Laravel hace que implementar autenticación sea sorprendentemente sencillo. Con Breeze tienes login y registro funcionando en minutos, y con Sanctum puedes proteger tu API con tokens de forma segura. Dominar estas dos herramientas es fundamental en el roadmap de cualquier desarrollador Laravel.