Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple middleware in controller Laravel 5.4

I want to use two middleware in __construct method in my controller. I was searching in google last few hours but didn't find any useful resource.

Here is my __construct with middleware:

public function __construct()
{
    $this->middleware('adminuser');
    $this->middleware('generaluser')->only('quizDetails','validateQuiz','attemptQuiz','submitQuiz','saveAnswer','setIndividualTime');
}

I want to give access those generaluser middleware method for General user. How i do that?

Please help me to solve this issues.

Thanks

like image 262
MD Iyasin Arafat Avatar asked Sep 21 '17 18:09

MD Iyasin Arafat


People also ask

How do I pass multiple middleware in Laravel?

You can assign multiple middlewares to Laravel route by using middleware method. Route::group(['middleware' => ['firstMiddleware','secondMiddleware']], function () { // }); This post is submitted by one of our members.

How do I add multiple middleware?

To assign middleware to a route you can use either single middleware (first code snippet) or middleware groups (second code snippet). With middleware groups you are assigning multiple middleware to a route at once. You can find more details about middleware groups in the docs.

Can we use multiple middleware?

Middlewares can be chained. We can use more than one middleware on an Express app instance, which means that we can use more than one middleware inside app. use() or app. METHOD() .

Can we apply middleware on controller in Laravel?

Laravel incorporates a middleware that confirms whether or not the client of the application is verified. If the client is confirmed, it diverts to the home page otherwise, it diverts to the login page. All controllers in Laravel are created in the Controllers folder, located in App/Http/Controllers.


4 Answers

So, you need to use something like "OR" for your middleware and it does not exist. Instead, you can use middleware parameters and do the magic inside your middleware.

Create a middleware to checking all your roles there instead of one middleware for each role.

use Closure;

class CheckRole
{
    public function handle($request, Closure $next, $role)
    {
        $roles = array_except(func_get_args(), [0,1]) // get array of your roles.

        // $request->user()->role IS AN EXAMPlE
        if (! in_array($request->user()->role, $roles)) {
            // Redirect...
        }

        return $next($request);
}

Next is to register it in kernel.php, routeMiddleware array:

'role' => \App\Http\Middleware\CheckRole::class,

Then you can check multiple roles at the same time

$this->middleware('role:adminuser')->only('functionA', 'functionB');

$this->middleware('role:adminuser,guestuser')->only('functionC', 'functionD');

Note: This is an example, you can change the logic inside middleware as you wish.

like image 187
Morteza Rajabi Avatar answered Oct 07 '22 01:10

Morteza Rajabi


Use the middleware in your routes file instead inside of the construct

Route::middleware(['adminuser'])->group(function () {

   //Only admins can access this

    Route::get('/','Controller@method');
    Route::get('/admins','Controller@method');
});

Route::middleware(['generaluser'])->group(function () {

    // General users access this

    Route::get('/users', 'Controller@method');
    Route::get('/generalusers', 'Controller@method');
});

If you want to use Two middlewares at same time

Route::middleware(['firstMiddleWare','secondMiddleWare'])->group(function () {
    Route::get('/aroute', 'Controller@method');
});

Routes that does not belong to a group will be available for all users

like image 35
Achraf Khouadja Avatar answered Oct 07 '22 01:10

Achraf Khouadja


I guess that adminuser middleware allows admin users and blocks the others, so a non-admin never reaches the generaluser middleware. You could try to exclude the generaluser methods from the adminuser middleware:

public function __construct()
{
    $this->middleware('adminuser')->except('quizDetails','validateQuiz','attemptQuiz','submitQuiz','saveAnswer','setIndividualTime');
    $this->middleware('generaluser')->only('quizDetails','validateQuiz','attemptQuiz','submitQuiz','saveAnswer','setIndividualTime');
}
like image 34
Ivan Avatar answered Oct 07 '22 01:10

Ivan


Many thanks Morteza Rajabi for giving me this idea, Here is the code i'm apply with his idea.

I'm create a new middleware for two user, here is code:

<?php

namespace App\Http\Middleware;

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

class RedirectIfNotAdminUserOrGeneralUser
{
    public function handle($request, Closure $next, $guard = null)
    {
        switch ($guard) {
            case 'adminuser':
                if (!Auth::guard($guard)->check()) {
                    return redirect('/');
                }
            break;
            case 'generaluser':
                if (!Auth::guard($guard)->check()) {
                    return redirect('/');
                }
            break;
        }
        return $next($request);
    }
}

And apply this in my controller, like this and give them access as i want. admin user can access all method and general user can access some of them. That's mean two user can access same method.

Here is controller code:

    public function __construct()
{
    $this->middleware('adminuser')->only('index','create','edit','store','delete','trashIndex','restore','permanentlyDelete','addGroups','addGroupsStore','addQuestions','addQuestionsStore','countGroup','countQuestion');
    $this->middleware('auserorguser')->only('quizDetails','validateQuiz','attemptQuiz','submitQuiz','saveAnswer','setIndividualTime');
}

Thanks again Morteza Rajabi.

like image 32
MD Iyasin Arafat Avatar answered Oct 07 '22 01:10

MD Iyasin Arafat