Last updated on February 17, 2018
In this post, I would like to show you very simple approach to develop a security layer around Laravel routes with custom Middleware.
Laravel Middleware
Middleware provides a convenient mechanism for filtering HTTP requests entering your application. middleware are series of “layers” where HTTP requests must pass through before they hit your application. Each layer can examine the request and even reject it entirely.
The Database
We will be using the following tables:
users: This table stores all of the user data.
roles: This table stores all of the roles lists.
For the sake of simplicity in this tutorial, one user can have only one role, so the role_id column added to the users’ table.
Generating and Running the Migrations
By default, Laravel 5 comes with a user table migration so just update it by adding role_id
column.
Now we need role migration, to create a roles table, generate a new migration by running php artisan make:migration create_roles_table
and add the following code to it.
increments('id'); $table->string('name'); $table->string('slug')->unique(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('roles'); } }
Now we have required migrations in place, to create tables run them using php artisan migrate
.
Creating and updating Models
By default, Laravel 5 comes with a User
model, so we do not have to create it. But We need to update it by adding the role method to it.
Add the following to the App\User
model.
public function role() { return $this->hasOne(Role::class); }
Now we need a Role
model, to generate run the following command php artisan make:model Role
.
Add your App\Role
model might be like below shown text
Creating middleware
Adding a middleware to provide role based access control is just as simple. To create a new middleware, use the
make:middleware
Artisan command:php artisan make:middleware RoleGateAbove command will place a new
RoleGate
class within yourapp/Http/Middleware
directory. In this middleware, we will only allow access to the route if the supplied role is assigned to the user. Otherwise, we will redirect the users back to the login URI.user() && $request->user()->role && $request->user()->role->slug === $role) { return $next($request); } return redirect('/login'); } }As you can see, if the given role is assigned to the currently authenticated user, the request will be passed further into the application, otherwise, the middleware will return an HTTP redirect to the login URI. To pass the request deeper into the application (allowing the middleware to "pass"), simply call the
$next
callback with the$request
.Registering Middleware
Open
app/Http/Kernel.php
and add your newly RoleGate middleware to the application's route middleware's array as shown below -protected $routeMiddleware = [ 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'role' => \App\Http\Middleware\RoleGate::class, ];How use it to protect roles
Once the middleware has been defined in the HTTP kernel, you may use the middleware method to assign middleware to a route:
Route::get('admin/profile', function () { // })->middleware('role:admin'); // allow only for role