Laravel Multiple Middleware in Route with OR Condition
Solution 1
If you change up the way your logic is thinking a little bit, the answer becomes pretty easy. You can create new middleware that checks if it can access the specific method.
So create the following middleware 'CanAccessIndex':
if (Auth::check()) {
if (Auth::user()->role == 'Admin' || Auth::user()->role == 'Premium') {
return $next($request);
}
}
return redirect('/home');
Then, you can put that middleware on the index function (instead of the premium middleware) and put your admin middleware on everything EXCEPT index. Like so:
public function __construct()
{
$this->middleware('canAccessIndex')->only('index');
$this->middleware('admin')->except('index');
}
That's one way to do it.
Solution 2
You need middleware group for this, and to manage these hierarchy of access layer, you can simply use Route grouping.
I will demo an example of what I mean:
Say you have auth
middleware general for authenticated users (i.e everybody), then another called premium
for premium member, and admin
for the Admin.
Then you'll group based on the access level:
Route::middleware('auth')->group(function(){
Route::middleware('premium')->group(function(){
Route::post('/create', 'HomeController@create')->middleware('admin');
Route::put('/update/{id}', 'HomeController@update')->middleware('admin');
Route::get('/index', 'HomeController@index');
Route::put('/delete/{id}', 'HomeController@delete')->middleware('admin');
});
});
So you can have general check in your middleware with a check. It would have been much easier if you have role level say 3 for admin and 2 for premium member. So we can have for the premium middleware:
public function handle($request, Closure $next)
{
return auth()->user->role >= 2
? $next($request)
: redirect('/home');
}
This is just an example. You can do further check based on your need but more importantly, ensure your admin
middleware to checks the exact role level that is allowed.
adrianriyadi
Updated on August 15, 2022Comments
-
adrianriyadi over 1 year
I wonder if I can do this in Laravel Route. Let's say I have
Admin
,Premium
andUser
(which can be login too by usingAuth
) Middleware. Also, I have controller with methods like this:index
,create
,edit
,delete
and I wantAdmin
to be able do all those things, butPremium
can only be able to accessindex
method, andUser
can't access anything in this controller (he can access another controller). I know I can useexcept
oronly
middleware method like this:public function __construct() { $this->middleware('premium')->only('index'); $this->middleware('admin'); // or maybe $this->middleware('admin')->except('index'); }
but when I try to put these two middlewares in
__construct
method they will start to conflict each other, it makes sense because index method can be access byPremium Member
but then can't be access by theAdmin
itself. Btw my middleware is simply checking:if (Auth::check()) { if (Auth::user()->role == 'Admin') { return $next($request); } } return redirect('/home');
So, back to my question, can I have OR Middleware so I can avoid conflict from multiple middleware (which is must be AND condition when they written at the same controller constructor)?
Thanks a lot.