Protecting all menus based on admin or customer role

Step 01: Changing in app.blade.php like following

@if(auth()->user()->role_id == 1)
<li class="nav-item">
	<a class="nav-link" href="{{ route('users.index') }}">{{ __('Users') }}</a>
</li>    
<li class="nav-item">
	<a class="nav-link" href="{{ route('products.index') }}">{{ __('Products') }}</a>
</li>
<li class="nav-item">
	<a class="nav-link" href="{{ route('profiles.index') }}">{{ __('Profile') }}</a>
</li>
<li class="nav-item">
	<a class="nav-link" href="{{ route('frame_widths.index') }}">{{ __('Frame Width') }}</a>
</li>                                                         
@endif
<li class="nav-item">
	<a class="nav-link" href="{{ route('orders.index') }}">{{ __('Orders') }}</a>
</li> 

Although these links are auth protected and related links will be shown based on admin or customer login. But admin links are not fully protected from customer role. Customer role can still access other admin links even if they are allowed for only order link.

To protect admin links from customer role we will need to use custom middleware which will serve this purpose.

Step 02: Running artisan command to create middleware

php artisan make:middleware IsAdmin

Step 03: Changing IsAdmin.php under app/Http/Middleware

public function handle($request, Closure $next)
{
	if(auth()->user()->role_id == 1){
		return $next($request);
	}

	return redirect('/orders')->with('error',"You don't have admin access.");
}

Step 04: Registering IsAdmin middleware inside app/Http/Kernal.php on $routeMiddleware array

protected $routeMiddleware = [
	'auth' => \App\Http\Middleware\Authenticate::class,
	'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
	'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
	'can' => \Illuminate\Auth\Middleware\Authorize::class,
	'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
	'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
	'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
	'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
	'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
	'is_admin' => \App\Http\Middleware\IsAdmin::class,
];

Step 05: Adding is_admin middleware back inside routes/web.php on all the routes

Route::group(['middleware'=> [ 'auth']], function() {

    Route::resource('orders', \App\Http\Controllers\OrderController::class);
    
    Route::group(['middleware'=> ['is_admin']], function() {
        Route::resource('users', \App\Http\Controllers\UserController::class);
        Route::resource('products', \App\Http\Controllers\ProductController::class);
        Route::resource('profiles', \App\Http\Controllers\ProfileController::class);
        Route::resource('frame_widths', \App\Http\Controllers\FrameWidthController::class);
    });    

}); 

Step 06: Adding flash message blade file in resources/views/flash-message.blade.php

@if ($message = Session::get('success'))
<div class="alert alert-success alert-dismissible">
    <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    <strong>{{ $message }}</strong>
</div>
@endif

@if ($message = Session::get('error'))
<div class="alert alert-danger alert-dismissible">
        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    <strong>{{ $message }}</strong>
</div>
@endif

@if ($message = Session::get('warning'))
<div class="alert alert-warning alert-dismissible">
        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    <strong>{{ $message }}</strong>
</div>
@endif

@if ($message = Session::get('info'))
<div class="aalert alert-info alert-dismissible">
        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    <strong>{{ $message }}</strong>
</div>
@endif

@if ($errors->any())
<div class="alert alert-danger alert-dismissible">
        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    Check the following errors :(
</div>
@endif

Step 07: Lastly adding flash-message.blade.php back inside resources/views/layouts/app.blade.php just before @yield('content')

<div class="container">
	<div class="row justify-content-center">
		<div class="col-8">
			@include('flash-message') 
		</div>
	</div>
</div>
@yield('content')

Now with authentication if customer tries to access admin links they will be redirected to orders list page showing flash message "you do not have admin access"

Related Posts


Building mini ecommerce in Laravel

Listing rows of users - crud

Adding user data - crud of users

Editing user data - crud of users

Deleting user data - crud of users

Listing rows of products - crud

Listing rows of profiles - crud

Listing rows of orders - crud

Listing rows of order items - crud