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

Ligonsker's avatar

Role-Based authorization or Gate-based authorization?

I am still not sure which design would be better:

Let's say I have many many routes. They are actually well organized in groups per routes, and some has many resources, so not just one post or one get:

Route::prefix('route_x')->group(function () {
    Route::get('/',
    Route::post('/store',
    Route::get('/{id}/sub_route_x',
    Route::post('{id}/sub_route_x/store',   
});

Route::prefix('route_y')->group(function () {
    Route::get('/',
    Route::post('/store',
    Route::get('/{id}/sub_route_y',
    Route::post('/{id}/sub_route_y/store',   
});

Now the app has a lot of indivudual screens and many groups of users that can use individual routes, and within these groups it's also divided to managers, staff and so on.

What would be a better way to implement authorization:

  1. Use role-based authorization, and then use it like so:
Route::prefix('route_x')->group(function () {
    Route::middleware(['role:route_x_managers,route_x_staff'])->group(function () {
        Route::get('/',
        Route::post('/store',
    });
    Route::middleware(['role:route_x_managers'])->group(function () {
        Route::get('/{id}/sub_route_x',
        Route::post('{id}/sub_route_x/store',   
    });
});
  1. Or, use it with gates and authorize routes per the route and the resources themselves:
Route::prefix('route_x')->group(function () {
    Route::middleware(['can:use_route_x'])->group(function () {
        Route::get('/',
        Route::post('/store',
    });
    Route::middleware(['can:use_route_x_sub_routes'])->group(function () {
        Route::get('/{id}/sub_route_x',
        Route::post('{id}/sub_route_x/store',   
    });
});

Or another solution?

0 likes
3 replies
jlrdw's avatar

It's basically the same thing you are giving permission that they role can or cannot do something.

Think about it like this and one big company you have many positions, okay let's say you have a mechanic and an accountant, now ask yourself do you want the mechanic to be able to go in and mess with accounting.

Authentication and authorization can be the trickiest to set up, but much of it is common sense in that a person can or cannot do something with his or her role.

1 like
Ligonsker's avatar

@jlrdw exactly, especially in this app there are many many positions (and many sub-positions to each).

I just wonder if choosing one over the other has advantages, maybe easier to maintain, easier to authorize new roles/permissions etc?

Maybe things I don't see that makes the can much better over the role or opposite. Because someone told me:

It's a really bad idea to authorize against roles. You really should use capabilities. If tomorrow you had to allow a new role to access a feature you now have numerous places in your code to update. If you instead authorize capabilities making a new distinct capability for each feature you only have the update your mapping between roles and capabilities.

But, in my case it looks almost the same?

azbx's avatar

These two are great options and can be explained as so:

Role-based authentication is the equivalent to me as @if(Auth::user()->admin == 1) do cool stuff @endif Now gating is more complicated @if(Auth::user()->sector_1_Access == true) //Allow @endif For me, Roles are better for moderation and gates are better for higher-ups to access only where they can go. Either way, you can do both using these techniques.

2 likes

Please or to participate in this conversation.