Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

peterpan26's avatar

how to restrict on the routes?

i currently have to restrict like this on blade anything:

  @php
    $userRoles = $userRolesData->pluck('role')->toArray();
@endphp
@if(in_array('Administrator', $userRoles))

how should i do the routes based on this and middleware? so i can restrict routes on the routes php effectivly?

class CheckUserRole
{
    public function handle($request, Closure $next, ...$roles)
    {
        // Check if the user is authenticated
        if (Auth::check()) {
            // Retrieve the user's role from the user_roles table
            $user = Auth::user();
            $userRole = DB::table('user_roles')->where('email', $user->email)->value('role');

            // Check if the user's role is one of the allowed roles
            if (in_array($userRole, $roles)) {
                return $next($request);
            }
        }

        // Redirect or handle unauthorized access
        return redirect()->route('login'); // Redirect to login route if the user is not authorized
    }
}
0 likes
13 replies
martinbean's avatar

@peterpan26 With middleware, like you’ve done so in the example above, and like you also did in your other thread asking about the exact same thing.

You should also have middleware do specific things. A middleware checking roles should not be doing authentication. That’s what the built-in auth middleware is for. You should “stack” your middleware to run one after the other. The auth middleware will redirect the user if they‘re not logged in. If they are authenticated, then your role middleware will run.

So, apply the middleware in order:

Route::middleware(['auth', 'role:administrator'])->group(function () {
    // Administrator-only routes...
});

Your middleware should then only be concerned with checking if the authenticated user has the requested roles:

class EnsureUserHasRole
{
    public function handle(Request $request, Closure $next, ...$roles)
    {
        $userRoles = $request->user()->roles()->pluck('role');

        foreach ($roles as $role) {
            if ($userRoles->contains($role)) {
                return $next($request);
            }
        }

        // If we are here, user does not have any of the requested role(s)
        // Return a 403 Forbidden response since they are logged in but do not have permission
        abort(403);
    }
}
martinbean's avatar

@Snapey They‘re checking if there’s an authenticated user in the very first line of their middleware?

if (Auth::check()) {
Snapey's avatar

@martinbean the code is copied from where? The OP does not say if what they have works or not.

peterpan26's avatar

I have a laravel code that if the login does a bind it logs the user in and matches the email he has on the session with the emails i have on CheckUserRole model and middleware. my doubt is how to restrict on routes.php based on the role from that table:

class CreateUserRolesTable extends Migration
{
    public function up()
    {
        Schema::create('user_roles', function (Blueprint $table) {
            $table->id();
            $table->string('email')->unique();
            $table->string('role');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('user_roles');
    }
}

class CheckUserRole
{
    public function handle($request, Closure $next, ...$roles)
    {
        // Check if the user is authenticated
        if (Auth::check()) {
            // Retrieve the user's role from the user_roles table
            $user = Auth::user();
            $userRole = DB::table('user_roles')->where('email', $user->email)->value('role');

            // Check if the user's role is one of the allowed roles
            if (in_array($userRole, $roles)) {
                return $next($request);
            }
        }

        // Redirect or handle unauthorized access
        return redirect()->route('login'); // Redirect to login route if the user is not authorized
    }
}

if i for example do the following :

Route::group(['middleware' => ['role:Supervisor']], function () {
      route here
    });

it's always logging out the user when i click in any of the routes, eventhough the email its logging in is a Supervisor email.

martinbean's avatar

my doubt is how to restrict on routes.php based on the role from that table:

@peterpan26 I’ve literally given you an example of this in my reply above.

The Laravel documentation on middleware parameters also has an example of checking of role as its example. Again, notice has the example in the Laravel docs does nothing around authentication; because you should be using Laravel’s built-in auth middleware to authenticate the user, and then separate middleware to check their role.

Please start reading instead of creating multiple threads on the same topic only to then ignore what people are telling you, and who have spent their free time and effort to type out examples for you.

peterpan26's avatar

the way im matching the email is on session:"

$email = $request->email;
                
        // Check if the email exists in the user_roles table
        $emailExists = DB::table('user_roles')->where('email', $email)->exists();
        
        // Retrieve roles associated with the email
        $userRolesData = DB::table('user_roles')->where('email', $email)->get();
        session(['userRolesData' => $userRolesData]);

with your example it keeps logging me out eventhough i have accessible email

martinbean's avatar

@peterpan26 Why do you need to submit an email address, when you can get the email address from the authenticated user? 🤷‍♂️

An email address submitted via an input can be easily changed by the user. It is not secure. If they find the email address of an admin user, then they will be able to then access things they shouldn’t be able to. But again, I’ve told you this already.

peterpan26's avatar

then how can i acces user email if i dont get access to users database?

peterpan26's avatar

i already too , told you i dont have access to user model nor user middlewares or anything related to user, i just if bind email and password on login i login if not i dont

martinbean's avatar

@peterpan26 What do you mean, you “don’t get access to users database”? It’s your application. Why don’t you have access to your own database?

It makes absolutely zero sense to be working with users’ roles if you don’t actually have “access” to those users in the first place.

peterpan26's avatar

ive already done with spatie laravel permitions in another versions of app but now with adldap in php laravel im only able to login with the bind because the users database its not mine

peterpan26's avatar

im already being able to restrict navbar items based on this:

  @php
    $userRoles = $userRolesData->pluck('role')->toArray();
@endphp
@if(in_array('Administrator', $userRoles))

and show the user email as {{ session('email') }} im just not being able to create the right middleware to restrict i have a user_roles table and match the emails on the bind with those if it matches it makes restrictions, so far theire only working on blade.php files not on middleware and apply it to the routes

Please or to participate in this conversation.