Proteger los recursos de tu aplicación para que solo su dueño pueda modificarlos o eliminarlos es una práctica fundamental en cualquier sistema web. Aquí se aborda cómo implementar una política de acceso sencilla utilizando una comparación de IDs y el helper abort, respaldando todo el proceso con un test automatizado.
¿Qué es una política de acceso y por qué la necesitas?
Una política de acceso es, en esencia, una regla que define quién puede realizar determinada acción sobre un recurso. En este caso, la regla es clara: solo el usuario que creó un repositorio puede actualizarlo o eliminarlo. Esto impide que otros usuarios modifiquen o borren repositorios ajenos.
La implementación parte de un if que compara el ID del usuario autenticado con el campo user_id almacenado en el repositorio. Si no coinciden, el sistema responde con un estado HTTP 403 [02:50].
¿Cómo funciona el estado HTTP 403?
El código de estado 403 Forbidden indica que el servidor entiende la solicitud, pero se niega a autorizarla. A diferencia de un 401 (Unauthorized), donde el problema es la autenticación, el 403 comunica que el usuario está autenticado pero no tiene permiso para ejecutar esa acción [02:56].
En la práctica, cuando un usuario intenta actualizar un repositorio que pertenece a otra persona, el servidor detiene la operación y devuelve este estado.
¿Cómo se implementa la validación en el controlador?
Dentro del método de actualización del controlador, justo después de la validación de datos, se agrega la siguiente lógica [03:30]:
php
if (auth()->user()->id !== $repository->user_id) {
abort(403);
}
- Se obtiene el ID del usuario autenticado mediante
auth()->user()->id.
- Se compara con el
user_id del repositorio que se intenta modificar.
- Si son diferentes, se ejecuta
abort(403), que lanza inmediatamente una respuesta HTTP 403.
- Si son iguales, la condición no se cumple y el flujo continúa con la actualización normal.
El helper abort() es una función que dispara estados HTTP de error de forma directa, deteniendo la ejecución del código restante.
¿Por qué el test recibía un 302 en lugar de un 403?
Antes de aplicar la política, al intentar actualizar un repositorio ajeno, el sistema respondía con un 302 (redirect) [03:10]. Esto ocurría porque la redirección era el comportamiento natural tras una actualización exitosa. Sin la verificación de propiedad, el sistema simplemente procesaba la solicitud sin restricciones.
¿Cómo se ajusta el test de actualización?
Al introducir la política, el test original de actualización también se rompe, porque el factory crea un usuario diferente al usuario autenticado [04:20]. La corrección consiste en:
- Crear primero el usuario que se va a autenticar.
- Crear el repositorio asignándole ese mismo usuario mediante el factory con datos personalizados.
php
$user = User::factory()->create();
$repository = Repository::factory()->create(['user_id' => $user->id]);
De esta forma, el usuario autenticado y el dueño del repositorio coinciden, y el test de actualización legítima vuelve a pasar correctamente.
¿Qué papel juega el factory en este contexto?
El factory de repositorios está configurado para crear automáticamente un nuevo usuario cada vez que genera un repositorio [01:50]. Esto significa que, sin personalización, el usuario autenticado (ID 1) y el dueño del repositorio (ID 2) serán personas distintas. Pasar el user_id de forma explícita al factory resuelve este desacople.
¿Cómo queda la cobertura de tests?
Al ejecutar todos los tests, se validan dos escenarios complementarios [05:10]:
- Política de acceso: un usuario no puede actualizar un repositorio que no le pertenece y recibe un 403.
- Actualización legítima: el dueño del repositorio puede actualizarlo sin problemas.
Ambos tests pasan satisfactoriamente, lo que confirma que la lógica está respaldada por pruebas automatizadas. En próximas iteraciones se refinará este código para hacerlo más robusto, pero lo esencial ya está funcionando y protegido.
¿Has implementado políticas de acceso de otra forma en tus proyectos? Comparte tu experiencia en los comentarios.