Search code examples
phplaravelcontrollermiddlewareguard

multiple controller middleware usiing same methods in Laravel 5.2


Im trying to use some methods of the same controller with diferent middlewares, for example let the admin and user use the methods index and create in the same controller. So I made an admin guard an a user guard.

This is my AdminMidleware

<?php

namespace App\Http\Middleware;

use Closure;
use Auth;

class AdminMidleware
{

    public function handle($request, Closure $next)
    {
        if (Auth::guard('admin')->guest()) {
            if ($request->ajax() || $request->wantsJson()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->guest('/');
            }
        }

        return $next($request);
    }
}

My UserMiddleware

<?php

namespace App\Http\Middleware;

use Closure;
use Auth;

class UserMiddleware
{

    public function handle($request, Closure $next)
    {
        if (Auth::guard('user')->guest()) {
            if ($request->ajax() || $request->wantsJson()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->guest('/');
            }
        }

        return $next($request);
    }
}

They both are in the kernel.php in $routeMiddleware

'admin' => \App\Http\Middleware\AdminMidleware::class,
'user' => \App\Http\Middleware\UserMiddleware::class,

If I use this I can make that only the admin get access to the methods, and it works, you have to be loged in as and admin to use the methods.

public function __construct(){
   $this->middleware('admin', ['only' => [
      'index',
      'create',
   ]]);
}

And this is suppose to make both user and admin able to use index and create methods in the same controller sending as first parametter an array with the admin and user middlewares,

public function __construct(){
   $this->middleware(['admin', 'user'], ['only' => [
      'index',
      'create',
   ]]);
}

But, it doesn't work, it actually makes no one able to use the methods, Could you help me make this work fine? What am I doing wrong?


Solution

  • Since your middleware are identical, except for the guard used, you can try to make an auth middleware that mimics the auth middleware that comes with the newer versions of Laravel. This would let you pass multiple guards as parameters to the middleware.

    public function handle($request, Closure $next)
    {
        // get guards or use 'null' (default guard)
        $guards = array_slice(func_get_args(), 2) ?: [null];
    
        // spin through guards to find one that checks out
        foreach ($guards as $guard) {
            if (Auth::guard($guard)->check()) {
                // if we have a guard name, not null
                if ($guard) {
                    // use this guard as the default
                    Auth::shouldUse($guard);
                }
    
                // we have an authed user from some guard move along
                return $next($request);
            }
        }
    
        // handle no authed user
        if ($request->ajax() || $request->wantsJson()) {
            return response('Unauthenticated.', 401);
        }
    
        return redirect()->guest('/');
    }
    

    It will spin through all the guards passed and if any of them resolve a user, that guard becomes the default guard that Auth will use.

    $this->middleware('thatmiddleware:user,admin');
    

    Something like that should work.