Cuando construyes una API en Laravel, garantizar que solo usuarios autorizados accedan a los recursos es tan importante como que los endpoints funcionen correctamente. Aquí se aborda cómo proteger rutas API mediante middleware de autenticación por token y cómo escribir tests que verifiquen tanto el acceso autorizado como el comportamiento ante usuarios invitados.
¿Cómo verificar que tu API rechaza usuarios no autorizados?
El punto de partida es un controlador con cinco métodos funcionales y un archivo de tests que ya cuenta con seis pruebas, incluyendo validaciones. El siguiente paso lógico es crear un test adicional que simule la llegada de un usuario invitado (no autenticado) a cada una de las rutas [01:06].
El método de prueba utiliza this->json() para enviar peticiones a las cinco rutas principales:
- GET
/api/post para el índice.
- POST
/api/post para crear.
- GET
/api/post/1000 para visualizar un registro.
- PUT
/api/post/1000 para actualizar.
- DELETE
/api/post/1000 para eliminar.
En cada caso, se espera recibir un status 401 (Unauthorized), que indica que el usuario no tiene autorización para acceder al recurso [01:30].
¿Por qué el test devuelve 200 en lugar de 401?
Al ejecutar las pruebas inicialmente, el sistema responde con un código 200 en vez del esperado 401. Esto ocurre porque la API es pública por defecto: no tiene ninguna capa de protección configurada [02:22].
Para solucionarlo, es necesario dirigirse al archivo api.php y agregar el middleware de autenticación. A diferencia de las rutas web donde se usa simplemente auth, en una API se configura la autenticación mediante token con auth:api [02:42].
php
Route::middleware('auth:api')->group(function () {
// Rutas protegidas del API
});
Tras aplicar el middleware, los tests del usuario invitado pasan correctamente: todas las rutas devuelven 401 cuando no hay sesión activa [03:04].
¿Cómo simular un usuario autenticado en los tests?
Proteger las rutas genera un problema inmediato: los tests existentes que verificaban funcionalidad (crear, leer, actualizar, eliminar) ahora fallan porque intentan acceder sin credenciales [03:30].
La solución es crear un usuario dentro de cada test utilizando el patrón factory y el método actingAs() [03:50].
php
$user = User::factory()->create();
Esta línea genera un usuario temporal en la base de datos de pruebas. Luego, se encadena actingAs() antes de la petición JSON para indicar que la solicitud se realiza como un usuario logueado [04:08]:
php
$this->actingAs($user, 'api')->json('GET', '/api/post');
¿Qué diferencia hay entre autenticación web y API en los tests?
El segundo parámetro de actingAs() es fundamental. Cuando se trabaja con rutas API, se debe pasar 'api' para que el login se aplique mediante token [04:22]. Si las pruebas fueran para rutas web definidas en web.php, este parámetro simplemente no se incluye.
Este patrón se repite en cada método de prueba:
- Se crea el usuario con factory.
- Se encadena
actingAs($user, 'api') antes de cada petición.
- El test verifica el comportamiento esperado con el usuario autenticado.
php
$user = User::factory()->create();
$this->actingAs($user, 'api')
->json('POST', '/api/post', $data)
->assertStatus(201);
¿Qué garantiza esta configuración completa?
Con esta implementación se logra una doble capa de verificación [05:52]:
- Cada método funcional confirma que un usuario logueado puede operar normalmente.
- El test de invitado confirma que las rutas están protegidas y devuelven 401 a usuarios sin token.
El resultado final al ejecutar las pruebas muestra todos los puntos en verde, confirmando que el backend está completamente configurado para recibir conexiones autenticadas por token [06:10]. Esto significa que cualquier frontend construido en JavaScript u otro framework necesitará implementar su propio sistema de login que se conecte a la API mediante token para consumir los recursos protegidos.
Comparte tus resultados de las pruebas en la sección de comentarios para comparar implementaciones.