How to use Middleware for content restriction based on user role in Laravel

Avinash Nethala
justlaravel
Published in
5 min readOct 24, 2017

Hello everyone, welcome back to justlaravel.com. Here in this post, I am going to show you how to use Middleware in your laravel applications to restrict content or some specific pages based on user role. This comes very handy when you have a simple paid membership site with where users who pay for a subscription can see pages which are not visible by other users. Or if you have admin, user, super admin type of roles, then also this Middleware in laravel works well.

Access Control is an important aspect of any application dealing with user-specific content. It provides with user’s ability to access specific applications components.

The official docs on this from laravel.com site here.

So let’s get started.

Middleware usage in Laravel — justlaravel.com

Setup User Roles

First I will create 3 user roles(admin, super admin, member) for testing our middleware functionality. I will create them by using laravel authentication scaffolding. So run the following command,

php artisan make:auth

Now we have login and registration setup, I will modify the registration script to add a new field “User Type”.

If you want to have a custom authentication — sigin/signup instead on this laravel scaffolding, I have made another post, you can look at them here.

First, add a new field to the user table, add this line $table->string('type'); to the user table create schema.

So locate the ###_create_users_table.php file at database\migrations direcctory.

public function up(){Schema::create(‘users’, function (Blueprint $table) {$table->increments(‘id’);$table->string(‘name’);$table->string(‘email’)->unique();$table->string(‘password’);$table->string(‘type’);$table->rememberToken();$table->timestamps();});}

Now migrate the tables, run the following command,

php artisan migrate

Navigate to the registration blade file at, \resources\views\auth\register.blade.php and below confirm password field and add a new select field as below,

<div class=”form-group”><label for=”type” class=”col-md-4 control-label” >User Type:</label><div class=”col-md-6"><select class=”form-control” name=”type” id=”type”><option value=”admin”>Admin</option><option value=”super_admin”>Super Admin</option><option value=”member”>Member</option></select></div></div>

Now the registration form looks like,

Middleware usage in Laravel — justlaravel.com

Now I will modify the controller to save the user type field in the database. I will add 'type' =&gt; $data['type'], to the create function at \app\Http\Controllers\Auth\RegisterController.php

Now the RegisterContoller’s create function will look like,

protected function create(array $data){return User::create([‘name’ => $data[‘name’],‘email’ => $data[‘email’],‘password’ => bcrypt($data[‘password’]),‘type’ => $data[‘type’],]);}

Also, I need to modify the model for users table. Add type to the fillable array.

Go to \app\User.php and modify the $fillable array

protected $fillable = [‘name’, ‘email’, ‘password’,’type’,];

Now the application is all ready to register users with a specific role.

Middleware for specific roles

So now I will create a middleware for each of the user role. In the terminal or command prompt run the following command in the root of your app.

php artisan make:middleware AdminMiddleware

The above command creates a new AdminMiddleware.php file at \app\Http\Middleware\

Similarly running the following commands, you can create middlewares for SuperAdmin and Member roles.

php artisan make:middleware SuperAdminMiddlewarephp artisan make:middleware MemberMiddleware

So open the AdminMiddleware.php file, and there I keep a check on user type and if user type is not admin, will display a message that this content is restricted to the user type

Modify the handle() function as below,

public function handle($request, Closure $next){if ($request->user() && $request->user()->type != ‘admin’){return new Response(view(‘unauthorized’)->with(‘role’, ‘ADMIN’));}return $next($request);}

Similarly for SuperAdminMiddleware,

public function handle($request, Closure $next){if ($request->user() && $request->user()->type != ‘super_admin’){return new Response(view(‘unauthorized’)->with(‘role’, ‘SUPER ADMIN’));}return $next($request);}

and for MemberMiddleware,

public function handle($request, Closure $next){if ($request->user() && $request->user()->type != ‘member’){return new Response(view(‘unauthorized’)->with(‘role’, ‘MEMBER’));}return $next($request);}

Now all the middleware files are ready, let’s make some separate routes particular for each user type.

So in \routes\web.php file, I will group all the particular middleware routes.

Route::group([‘middleware’ => ‘App\Http\Middleware\AdminMiddleware’], function(){Route::match([‘get’, ‘post’], ‘/adminOnlyPage/’, ‘HomeController@admin’);});

In the above snippet, I grouped all the admin related routes. Actually, I have written only one route(/adminOnlyPage/) but you can write as many routes as possible there.

Similarly for SuperAdmin,

Route::group([‘middleware’ => ‘App\Http\Middleware\MemberMiddleware’], function(){Route::match([‘get’, ‘post’], ‘/memberOnlyPage/’, ‘HomeController@member’);});

And for Member,

Route::group([‘middleware’ => ‘App\Http\Middleware\SuperAdminMiddleware’], function(){Route::match([‘get’, ‘post’], ‘/superAdminOnlyPage/’, ‘HomeController@super_admin’);});

Views and Controllers for Middleware

In the above route snippets, I have set up some methods in HomeController. And in the middleware, I am passing an unauthorized view page in the middleware file.

So in that view. I will display a simple message as below in the file \resources\views\unauthorized.blade.php

<div class=”title m-b-md”>You cannot access this page! This is for only ‘{{$role}}’”</div>
Middleware usage in Laravel — justlaravel.com

And in HomeController, I just return to a view for each user type link.

public function admin(Request $req){return view(‘middleware’)->withMessage(“Admin”);}public function super_admin(Request $req){return view(‘middleware’)->withMessage(“Super Admin”);}public function member(Request $req){return view(‘middleware’)->withMessage(“Member”);}

The view for middleware page.

<div class=”title m-b-md”>{{ strtoupper($message)}} only page!</div>
Middleware usage in Laravel — justlaravel.com

And finally after login, I will show 3 links of all the user types irrespective of any user logged in.

In the file \resources\views\home.blade.php

<div class=”panel panel-default”><div class=”panel-heading”>Dashboard</div><div class=”panel-body”>You are logged in! as <strong>{{ strtoupper(Auth::user()->type) }}</strong>Admin Page: <a href=”{{ url(‘/’) }}/adminOnlyPage”>{{ url(‘/’) }}/adminOnlyPage</a>Super Admin Page: <a href=”{{ url(‘/’) }}/superAdminOnlyPage”>{{ url(‘/’) }}/super_adminOnlyPage</a>Member Page: <a href=”{{ url(‘/’) }}/memberOnlyPage”>{{ url(‘/’) }}/memberOnlyPage</a></div></div>
Middleware usage in Laravel — justlaravel.com

So when you click on any of the links above, if the logged in user has access to that page it shows the content or else a message shows that your are not authorized to access the page.

That is it about this application. Here I used a very generic example with only one route for each group to make it simple. You can extend this understanding to implement the way you want.

--

--