Laravel Sanctum vs Passport en 2026: Autenticación de API y Preguntas de Entrevista

Comparación técnica de Laravel Sanctum y Passport para autenticación de API en 2026. Guía práctica con ejemplos de código y preguntas de entrevista técnica.

Laravel Sanctum vs Passport en 2026: Autenticación de API y Preguntas de Entrevista

Laravel Sanctum y Passport cubren diferentes necesidades de autenticación de API, y elegir el paquete incorrecto conduce a complejidad innecesaria o brechas de seguridad. Esta guía desglosa ambos paquetes con ejemplos de código prácticos y preguntas reales de entrevistas.

Decisión Rápida

Sanctum maneja la autenticación de SPAs y tokens de API simples. Passport implementa OAuth2 completo con códigos de autorización, credenciales de cliente y tokens de actualización. La mayoría de las aplicaciones necesitan Sanctum.

Laravel Sanctum vs Passport: Diferencias Fundamentales

Sanctum proporciona autenticación ligera basada en tokens diseñada para aplicaciones first-party. El paquete utiliza autenticación basada en cookies de sesión para SPAs y tokens de acceso personal para aplicaciones móviles y APIs simples.

Passport implementa la especificación OAuth2 completa, incluyendo servidores de autorización, grants de credenciales de cliente y autenticación machine-to-machine. Esta complejidad tiene sentido para aplicaciones que necesitan autorizar acceso de terceros.

| Característica | Sanctum | Passport | |----------------|---------|----------| | Caso de Uso Principal | SPAs, Apps Móviles, APIs Simples | OAuth2 Terceros, Machine-to-Machine | | Tipo de Token | Tokens hasheados simples | JWT con scopes OAuth2 | | Auth de Sesión | Sí (basado en cookies) | No | | Grants OAuth2 | Ninguno | Especificación completa | | Tamaño del Paquete | Mínimo | Significativo | | Configuración | Simple | Compleja |

Implementando Sanctum para Autenticación SPA

La autenticación SPA de Sanctum se basa en cookies de sesión de Laravel en lugar de tokens de API. El frontend y el backend deben compartir el mismo dominio de nivel superior para que esto funcione.

config/sanctum.phpphp
return [
    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
        '%s%s',
        'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
        env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
    ))),

    'expiration' => null, // Tokens never expire by default

    'middleware' => [
        'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
        'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
    ],
];

El SPA debe llamar al endpoint de cookie CSRF antes de realizar solicitudes autenticadas. Esto establece la sesión y configura la cookie XSRF-TOKEN.

javascript
// Frontend: Initialize CSRF protection before login
async function initializeAuth() {
    await fetch('/sanctum/csrf-cookie', {
        credentials: 'include'
    });
}

async function login(email, password) {
    await initializeAuth();
    
    const response = await fetch('/api/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-XSRF-TOKEN': getCookie('XSRF-TOKEN'),
            'Accept': 'application/json'
        },
        credentials: 'include',
        body: JSON.stringify({ email, password })
    });
    
    return response.json();
}

Autenticación con Token de API en Sanctum

Las aplicaciones móviles e integraciones de terceros utilizan tokens de acceso personal en lugar de cookies de sesión. Sanctum almacena estos tokens como hashes SHA-256 en la base de datos.

app/Http/Controllers/AuthController.phpphp
namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller
{
    public function createToken(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
            'device_name' => 'required',
        ]);

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

        if (! $user || ! Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'email' => ['The provided credentials are incorrect.'],
            ]);
        }

        // Token with abilities (scopes)
        $token = $user->createToken(
            $request->device_name,
            ['read', 'write'] // Optional abilities
        );

        return response()->json([
            'token' => $token->plainTextToken,
            'expires_at' => null // Configure in sanctum.php
        ]);
    }

    public function revokeToken(Request $request)
    {
        // Revoke current token
        $request->user()->currentAccessToken()->delete();

        return response()->json(['message' => 'Token revoked']);
    }
}

La protección de rutas se realiza con el middleware auth:sanctum. La verificación de las abilities del token utiliza el método tokenCan.

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

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

    Route::post('/posts', function (Request $request) {
        // Check if token has write ability
        if (! $request->user()->tokenCan('write')) {
            abort(403, 'Token does not have write permissions');
        }

        // Create post logic
    });
});

¿Listo para aprobar tus entrevistas de Laravel?

Practica con nuestros simuladores interactivos, flashcards y tests técnicos.

Cuándo Usar Laravel Passport

Passport se vuelve necesario cuando la aplicación actúa como servidor de autorización OAuth2. Los escenarios comunes incluyen:

  • Desarrolladores de terceros construyendo integraciones con la API
  • Autenticación machine-to-machine entre microservicios
  • Aplicaciones que requieren conformidad OAuth2 para clientes empresariales
  • Sistemas que necesitan rotación de tokens de actualización y validación JWT
app/Http/Controllers/Api/PassportController.phpphp
namespace App\Http\Controllers\Api;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class PassportController extends Controller
{
    public function issueToken(Request $request)
    {
        $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([
                'error' => 'invalid_credentials'
            ], 401);
        }

        // Create OAuth2 token with scopes
        $token = $user->createToken('API Token', ['read-posts', 'write-posts']);

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

Passport también soporta el grant de credenciales de cliente para autenticación servidor-a-servidor sin contexto de usuario.

php
// Machine-to-machine authentication
// config/auth.php
'guards' => [
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

// routes/api.php - Client credentials protected route
Route::middleware('client')->group(function () {
    Route::get('/machine-data', function () {
        return response()->json(['data' => 'Machine accessible']);
    });
});

Mejores Prácticas de Seguridad para Autenticación de API en Laravel

Ambos paquetes requieren medidas de seguridad adicionales más allá de la configuración básica. La expiración de tokens, el rate limiting y la validación adecuada de scopes previenen vulnerabilidades comunes.

app/Providers/AuthServiceProvider.phpphp
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Laravel\Sanctum\Sanctum;
use Laravel\Sanctum\PersonalAccessToken;

class AuthServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        // Set token expiration (Sanctum)
        Sanctum::authenticateAccessTokensUsing(function ($token, $isValid) {
            // Expire tokens after 24 hours
            $expiration = config('sanctum.expiration');
            
            if ($expiration === null) {
                return $isValid;
            }

            return $isValid && $token->created_at->gt(now()->subMinutes($expiration));
        });
    }
}

La implementación de rate limiting en endpoints de autenticación previene ataques de fuerza bruta. Laravel 12 proporciona configuración flexible del rate limiter a través de la facade RateLimiting.

app/Providers/AppServiceProvider.phpphp
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiting;

public function boot(): void
{
    RateLimiting::for('login', function ($request) {
        return Limit::perMinute(5)->by($request->ip());
    });

    RateLimiting::for('api', function ($request) {
        return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
    });
}

Preguntas de Entrevista sobre Autenticación en Laravel

Las entrevistas técnicas frecuentemente evalúan la comprensión de los patrones de autenticación de API. Estas preguntas aparecen en entrevistas de desarrolladores Laravel de todos los niveles.

P: ¿Cuál es la diferencia entre la autenticación SPA y la autenticación por token de Sanctum?

La autenticación SPA utiliza cookies de sesión de Laravel con protección CSRF. El frontend llama a /sanctum/csrf-cookie para establecer una sesión, luego las solicitudes posteriores incluyen automáticamente la cookie de sesión. La autenticación por token utiliza tokens Bearer en el encabezado Authorization, adecuada para aplicaciones móviles e integraciones de terceros donde las cookies son impracticables.

P: ¿Cuándo elegir Passport en lugar de Sanctum?

Passport implementa OAuth2 completo, requerido cuando desarrolladores de terceros necesitan integrarse con la API usando el flujo de código de autorización, o cuando la autenticación machine-to-machine requiere grants de credenciales de cliente. Sanctum maneja aplicaciones first-party de manera más simple.

P: ¿Cómo almacena Sanctum los tokens de API?

Sanctum almacena el hash SHA-256 de cada token en la tabla personal_access_tokens. El token en texto plano se devuelve solo una vez durante la creación. Este enfoque significa que datos de base de datos comprometidos no pueden revelar tokens válidos.

P: ¿Cómo implementar abilities/scopes de token en Sanctum?

php
// Creating token with abilities
$token = $user->createToken('api-token', ['posts:read', 'posts:write']);

// Checking abilities in controller
if ($request->user()->tokenCan('posts:write')) {
    // Authorized for write operations
}

// Middleware-based ability check
Route::middleware(['auth:sanctum', 'ability:posts:write'])
    ->post('/posts', [PostController::class, 'store']);

P: ¿Cómo revocar todos los tokens de un usuario en Sanctum?

php
// Revoke all tokens
$user->tokens()->delete();

// Revoke specific token by ID
$user->tokens()->where('id', $tokenId)->delete();

// Revoke current token only
$request->user()->currentAccessToken()->delete();

Migración de Passport a Sanctum

Las aplicaciones que comenzaron con Passport pero solo usan autenticación por token simple pueden migrar a Sanctum para reducir la complejidad. La migración requiere actualizar la creación de tokens, la configuración del middleware y cualquier verificación de scopes.

php
// Migration helper: Convert Passport tokens to Sanctum
use App\Models\User;
use Laravel\Passport\Token;

// This is a one-way migration - run once then remove Passport
User::chunk(100, function ($users) {
    foreach ($users as $user) {
        $passportTokens = Token::where('user_id', $user->id)
            ->where('revoked', false)
            ->get();

        foreach ($passportTokens as $token) {
            $user->createToken(
                $token->name ?? 'migrated-token',
                $token->scopes ?? []
            );
        }
    }
});

La actualización del middleware de rutas de auth:api a auth:sanctum y el reemplazo de $request->user()->token()->scopes por $request->user()->currentAccessToken()->abilities son necesarios.

Conclusión

  • Sanctum es ideal para SPAs, aplicaciones móviles y APIs first-party con configuración mínima
  • Passport maneja servidores de autorización OAuth2 e integraciones de terceros
  • La autenticación SPA usa cookies de sesión; la autenticación de API usa tokens Bearer
  • Las abilities de token proporcionan control de permisos granular en Sanctum
  • El rate limiting y la expiración de tokens son medidas de seguridad esenciales sin importar el paquete elegido
  • La mayoría de las aplicaciones Laravel deberían comenzar con Sanctum y solo agregar Passport cuando la conformidad OAuth2 se vuelva un requisito

¡Empieza a practicar!

Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.

Compartir

Artículos relacionados