Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use 'OR' middleware for route laravel 5

I've two types for user and I've created multiple middlewares.

Some routes need to allow for both type of user.

I've trying following code:

Route::group(['namespace' => 'Common', 'middleware' => ['Auth1', 'Auth2']], function() {
    Route::get('viewdetail', array('as' => 'viewdetail', 'uses' => 'DashboardController@viewdetail'));
}); 

But its not working :(

like image 490
Govind Samrow Avatar asked Sep 06 '16 09:09

Govind Samrow


People also ask

How do you use auth middleware in route Laravel?

php file in your routes folder, then create your routes for Admin: <? php use Illuminate\Support\Facades\Route; // This route's name will be 'admin. dashboard' Route::get('dashboard', 'DashboardController@dashboard')->name('dashboard'); // This route's name will be 'admin.

What is middleware in Laravel route?

Assigning Middleware To Routes If you would like to assign middleware to specific routes, you should first assign the middleware a key in your application's app/Http/Kernel.php file. By default, the $routeMiddleware property of this class contains entries for the middleware included with Laravel.


3 Answers

This example How to pass multiple parameters to middleware with OR condition in Laravel 5.2

Instead of adding multiple arguments to your handle method and having to update it every time you add a new role to your application, you can make it dynamic.

Middleware

 /**
 * Handle an incoming request.
 *
 * @param $request
 * @param Closure $next
 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
 */
public function handle($request, Closure $next) {

    $roles = array_slice(func_get_args(), 2); // [default, admin, manager]

    foreach ($roles as $role) {

        try {

            Role::whereName($role)->firstOrFail(); // make sure we got a "real" role

            if (Auth::user()->hasRole($role)) {
                return $next($request);
            }

        } catch (ModelNotFoundException $exception) {

            dd('Could not find role ' . $role);

        }
    }

    Flash::warning('Access Denied', 'You are not authorized to view that content.'); // custom flash class

    return redirect('/');
}

Route

Route::group(['middleware' => ['role_check:default,admin,manager']], function() {
    Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
});

This will check if the authenticated user has at least one of the roles provided and if so, passes the request to the next middleware stack. Of course the hasRole() method and the roles themselves will need to be implemented by you.

You can use php 5.6

public function handle($request, Closure $next, ...$roles)
{
    foreach ($roles as $role) {

        try {
            if ($request->user()->can($role)) {
              return $next($request);
        }

        } catch (ModelNotFoundException $exception) {
          abort(403);
        }
    }

}
like image 35
ztvmark Avatar answered Oct 16 '22 11:10

ztvmark


Middleware is supposed to either return a response or pass the request down the pipeline. Middlewares are independent of each other and shouldn't be aware of other middlewares run.

You'll need to implement a separate middleware that allows 2 roles or single middleware that takes allowed roles as parameters.

Option 1: just create a middleware is a combined version of Auth1 and Auth2 that checks for 2 user types. This is the simplest option, although not really flexible.

Option 2: since version 5.1 middlewares can take parameters - see more details here: https://laravel.com/docs/5.1/middleware#middleware-parameters. You could implement a single middleware that would take list of user roles to check against and just define the allowed roles in your routes file. The following code should do the trick:

// define allowed roles in your routes.php
Route::group(['namespace' => 'Common', 'middleware' => 'checkUserRoles:role1,role2', function() {
  //routes that should be allowed for users with role1 OR role2 go here
}); 

// PHP < 5.6
// create a parametrized middleware that takes allowed roles as parameters
public function handle($request, Closure $next) {

  // will contain ['role1', 'role2']
  $allowedRoles = array_slice(func_get_args(), 2);

  // do whatever role check logic you need
}

// PHP >= 5.6
// create a parametrized middleware that takes allowed roles as parameters
public function handle($request, Closure $next, ...$roles) {

  // $roles will contain ['role1', 'role2']

  // do whatever role check logic you need
}
like image 170
jedrzej.kurylo Avatar answered Oct 16 '22 09:10

jedrzej.kurylo


Route::group(['middleware' => 'role:manager,admin'], function () {}

In middleware named 'role' you can destruct arguments into array

public function handle($request, Closure $next, ...$roles)
{
    $userRole = $request->user()->role;

    if (! $userRole || ! in_array($userRole->name, $roles)) {
        abort(403);
    }

    return $next($request);
}
like image 2
AID Avatar answered Oct 16 '22 11:10

AID