laravel

Laravel: restringir acceso según rol de usuario

En el post te hoy te enseñaré a manejar algunos roles de usuario en Laravel para que se pueda acceder a ciertas áreas dependiendo del rol.

Con lo que aprenderás podrás restringir ciertos módulos solo al administrador, y otros solo para el usuario normal, cajero, empleado, etcétera. Vamos a usar controladores y middlewares.

Por cierto, con esto vamos a restringir controladores completos, y no acciones. Eso lo dejamos para otro post en donde seguramente usaremos los Requests y el método authorize.

Agregando el rol de usuario

Primero debes hacer una migración para agregar el campo a la base de datos, modificar el modelo en sus fillables, etcétera.

Eso no lo explicaré en este post, aquí supondré que ya sabes recuperar el usuario con su rol.

Luego puedes obtener el rol del usuario que inició sesión con Auth::user()->rol (suponiendo que rol es el campo del rol).

Creando middleware

Nota: si esto cambia en una actualización de Laravel simplemente sigue los pasos de la documentación para crear uno.

El siguiente paso es crear un middleware de Laravel que va a restringir el acceso en caso de que el rol del usuario no sea el de administrador (o el rol que tú quieras).

Ejecutamos php artisan make:middleware SoloUsuarioAdministrador

Eso creará un archivo llamado SoloUsuarioAdministrador dentro de app/Http/Middleware.

En su método handle verificamos si el rol es administrador. En caso de que sí, dejamos que la petición se cumpla invocando a $next pasándole el $request.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class SoloUsuarioAdministrador
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */    public function handle(Request $request, Closure $next)
    {
        if (Auth::user()->rol === "administrador") {
            return $next($request);
        } else {
            return redirect()->back()->with("mensaje", "No puedes acceder al módulo seleccionado");
        }
    }
}

En caso contrario, lo redireccionamos hacia atrás (con redirect()->back()) y le indicamos con un mensaje. Recuerda que tú puedes manejarlo como prefieras; podrías simplemente regresar un mensaje, redireccionar a otra página, etcétera.

Finalmente en app/Http/Kernel.php dentro de $routeMiddleware indicamos nuestro middleware al final. Yo le puse el nombre solo_usuario_administrador.

<?php
protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'solo_usuario_administrador' => SoloUsuarioAdministrador::class,
    ];

No olvides importarlo con use App\Http\Middleware\SoloUsuarioAdministrador; al inicio.

Hasta el momento solo tenemos el middleware creado, falta aplicarlo.

Aplicando middleware para verificar rol de usuario con Laravel

Ya tenemos el middleware y el rol del usuario, ahora solo hay que aplicarlo a las rutas que creamos necesarias.

Con Laravel podemos agrupar rutas y eso es justamente lo que haremos. En mi caso tengo algunos módulos que puede ver cualquier usuario autenticado, y otros que solo puede ver el administrador.

<?php

use App\Http\Controllers\CancionController;
use App\Http\Controllers\CancionSolicitadaController;
use App\Http\Controllers\EstacionController;
use App\Http\Controllers\GeneroController;
use App\Http\Controllers\ReporteController;
use App\Http\Controllers\UserController;
use App\Models\CancionSolicitada;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get("/", function () {
 return redirect()->route("login");
});
Route::get("/usuarios_login", [UserController::class, "login"])->name("login");
Route::post("/usuarios_login", [UserController::class, "hacerLogin"])->name("hacerLogin");
Route::get("/usuarios_logout", [UserController::class, "logout"])->name("logout");
Route::get("/usuarios_password_reset", [UserController::class, "formPasswordReset"])->name("formPasswordReset");
Route::post("/usuarios_password_reset", [UserController::class, "passwordReset"])->name("passwordReset");
Route::get("/restablecer-password/{token}", function ($token) {
 return view('usuarios.reset-password', ['token' => $token]);
})->name("password.reset");
Route::post("/password-update", [UserController::class, "passwordUpdate"])->name("password.update");

Route::middleware(["auth"])->group(function () {
 Route::resource("estaciones", EstacionController::class)->parameters(["estaciones" => "estacion"]);
 Route::resource("generos", GeneroController::class)->parameters(["generos" => "genero"]);
 Route::resource("canciones", CancionController::class)->parameters(["canciones" => "cancion"]);
 Route::resource("canciones_solicitadas", CancionSolicitadaController::class)->parameters(["canciones_solicitadas" => "cancionSolicitada"]);
 Route::get("/reportes", [ReporteController::class, "index"])->name("reportes.index");
 Route::post("/reportes", [ReporteController::class, "store"])->name("reportes.store");
});

Route::middleware(["auth", "solo_usuario_administrador"])->group(function () {
 Route::resource("usuarios", UserController::class)->parameters(["usuarios" => "user"]);
});

Por ejemplo, desde la línea 23 hasta la 34 definimos las rutas públicas a la que cualquier usuario puede acceder incluso sin estar logueado; son rutas que no necesitan rol.

Luego desde la línea 36 hasta la 43 defino los controladores y resources a los que solo los usuarios autenticados tendrán acceso.

Y finalmente en la línea 45 hasta la 47 estoy indicando las rutas a las que se podrá acceder solo si el usuario autenticado es administrador, aplicando el middleware auth además del solo_usuario_administrador.

Conclusión

Aunque parezca algo tardado, no lo es. Laravel ofrece varias maneras de comprobar la autenticación de usuarios y sus roles.

Con lo que hicimos podremos agregar más rutas y protegerlas o separarlas agregando los middleware necesarios para controlar el acceso a los módulos dependiendo del rol del usuario con Laravel.

Para finalizar te dejo con más tutoriales de Laravel y PHP en mi blog.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

3 días hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

3 días hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

3 días hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

3 días hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

3 días hace

Solución: Apache – Server unable to read htaccess file

Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…

4 días hace

Esta web usa cookies.