0

I have two types of user roles. Admin and manager. An admin can to to all the routes, but a manager can only access some of them. Most of my routes are resource route. Currently I have this route group for admin:

Route::middleware(['auth', 'admin'])->prefix('admin')->group(function () {
    Route::resource('post','PostController')
}

Here is my 'admin' middleware if you need to check:

if (!Auth::user()->isAdmin())
    {
        return redirect('/home');
    }
    return $next($request);

Here, all the routes are accessible by the admin. But I want to allow access some of the routes such as post.index, post.show, post.edit for the manager. What should I do now?

Below I am explaining my question elaborately with and example

I have three middleware, auth, manager, admin. As the name suggests, auth middleware checks if a user is authenticated, manager middleware checks if the user is manager and certainly admin middleware checks if the user is admin. Now, for Route::resource('post','PostController') route,

  • auth has access to post.index, post.view
  • manager has access to post.index, post.view, post.edit
  • admin has access to all the routes. What is the best way to apply middleware to solve the problem?
Yeasir Arafat
  • 1,425
  • 1
  • 13
  • 28
  • 1
    Define route groups and assign middleware specific to those groups. If want more control over access level, use ACL. – ash__939 Aug 03 '20 at 09:04
  • Does this answer your question? [assign separate middleware to each method of a resource in laravel](https://stackoverflow.com/questions/36444779/assign-separate-middleware-to-each-method-of-a-resource-in-laravel) – jewishmoses Aug 03 '20 at 09:11
  • You will have prefix `admin` for all routes. If you give access to manager for certain `admin` routes, at least the URL should be amended accordingly. – nice_dev Aug 03 '20 at 09:16

2 Answers2

4

Laravel allows for multiple routes in your controllers

Follow the following steps:

Remove the 'admin' middleware from your route group, leaving just 'auth'.

    Route::middleware(['auth'])->prefix('admin')->group(function()
    {
        Route::resource('post','PostController');
    }

In your 'manager.php' route file now, you can use and point to the same PostController

Route::middleware(['auth'])->prefix('manager')->group(function()
{
    Route::resource('post','PostController');
}

then add a __construct() method at the top of the PostController like this

class PostController extends Controller
{
    public function __construct()
    {
        $this->middleware('admin')->except(['index', 'show', 'edit']);
        $this->middleware('manager');
    }
}
  • I do not have a **manager.php** file. Should I have one? I have a user model where I have specified a role attribute if a user is an admin or manager. – Yeasir Arafat Aug 03 '20 at 09:39
  • @Yeasir Arafat Hridoy - Laravel also supports having multiple route files, which was why I assumed you are using not just the web.php file for all your routes. But If you’re using just the web.php file for all your routes, you can still add the route in there also. It’ll still the same....please don’t forget to mark my answer as valid answer if it helped you. – Babalola Macaulay Aug 03 '20 at 10:51
0

You can define partial ressource routes.

https://laravel.com/docs/7.x/controllers#restful-partial-resource-routes

So you can define some of them in your middleware group and the other ones outside of it.

Route::middleware(['auth'])->group(function(){
 Route::middleware(['admin'])->prefix('admin')->group(function () {
    Route::resource('post','PostController')->except([
    'index', 'show', 'edit'
     ]);
 }
 Route::middleware(['manager'])->prefix('manager')->group(function () {
  Route::resource('post','PostController')->only([
    'index', 'show', 'edit'
  ]);
 }
}
Aless55
  • 2,652
  • 2
  • 15
  • 26
  • 1
    This looks incorrect because all along with admin and manager have access to it. – nice_dev Aug 03 '20 at 09:15
  • @vivek_23, index, show and edit should be accessed by both, the other ones are secured in the admin middleware, so where does it go wrong? – Aless55 Aug 03 '20 at 09:22
  • I need another middleware for manager that checks if the user is a manager. There is no `manager` middleware. – Yeasir Arafat Aug 03 '20 at 09:44
  • @Aless55 Assume I am an employee and neither a manager nor the admin. Then? – nice_dev Aug 03 '20 at 09:57
  • 1
    @vivek_23 i edited my answer, now it should take this into account, it also depends what the manager middleware is checking, but now it should work the same as the answer with 4 upvotes – Aless55 Aug 03 '20 at 09:59
  • @Aless55 will the `manager` middleware allow an admin to access the routes that have been applied `manager` middleware? `manager` middleware allows only the manager, not the admin. I can allow both manager and admin in manager middleware, but I can not do it because for other cases, a manager should have access to something that and admin should not have. – Yeasir Arafat Aug 03 '20 at 10:05
  • We always do it like that, we have like a hierarchy in our roles system, if you want to call it like that. But if you have such a case you can create a new middleware or check for a certain permission. @YeasirArafatHridoy – Aless55 Aug 03 '20 at 10:52