In this article, we will discuss the “Laravel Authorization with Gates”. As you know, Laravel provided an Authentication solution that is Out of the box. Laravel provides two simple way to manage the authentications such as Gates and Policies. The basic difference between the gates and the policies, Gates provides a simple closure based approach to authorization and policies works around the particular model or resource. Today, we discuss how to implement the Gates in our Laravel Application.
Table of Contents
Where we use Gates?
Gates are mostly implemented on the action which is not related to any model or resource. For example the Admin dashboard, we want to allow a user with the admin role can access the admin dashboard. Here, we implement a Gate that verifies user roles and applies restrictions if required.
Prerequisite
We need a copy of the Laravel setup, where we implement our example. I’m assuming, you are familiar with the installation and Laravel setup process so I’m not adding the basic details here. If, you are fresh in Laravel then please check our Laravel articles.
Update User Migration
Here, we have to add the required role to our user table. So open users table migration file located at “database\migrations”.
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->string('role', 50)->default('guest'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
Create New Migration for role Column
If, your application is already migrated with the existing migrations. Then you can create a migration for the role column as given below.
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class AddRoleInUsers extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { $table->string('role', 50)->default('guest'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->string('role', 50)->default('guest'); }); } }
Update Model
After creating or updating the migrations. You have to add the role column in your user model fillable.
protected $fillable = [ ... 'role' ];
Define Gates
Here, we define multiple gates as per our role base requirement. I’m creating three types of gates such as isAdmin, isEditor, and isGuest.
- isAdmin – return true if the user role is admin.
- isEditor – return true if the user role is an editor.
- isGuest – return true if the user role is guest.
<?php namespace App\Providers; use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * * @var array */ protected $policies = [ // 'App\Model' => 'App\Policies\ModelPolicy', ]; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); /** * Define Gate for admin user role * Returns true if user role is set to admin **/ Gate::define('isAdmin', function($user) { return $user->role == 'admin'; }); /** * Define Gate for editor user role * Returns true if user role is set to editor **/ Gate::define('isEditor', function($user) { return $user->role == 'editor'; }); /** * Define Gate for guest user role * Returns true if user role is set to guest **/ Gate::define('isGuest', function($user) { return $user->role == 'guest'; }); } }
Use Gate with Middleware
When we define our application routes then we can use the default middleware “can:<GATE_NAME>” as given below.
// Admin Only Route::middleware('can:isAdmin')->prefix('admin')->group(function () { // Mention all admin routes Route::get('/', 'AdminController@index'); });
Use Gate in Controller
In the controller, there is two way to implements the Gates as per given examples.
In the first example, I’m using the allows method. Using authorize action using gates, Laravel provides two methods such as allows or denies. No need to pass the currently authenticated user to these methods. Laravel handles this automatically and passes the user into the gate closure. You can read the official documentation for more details.
In the second example, I’m using the authorize method. It’s a default method given by Laravel. Like the “can” method, this method accepts the name of the action you wish to authorize and the relevant model. If authorization failed then “authorize” method will throw an exception “Illuminate\Auth\Access\AuthorizationException”, 403 error is present on the screen.
/** * Example 1 * @return Error Message */ public function index() { if (\Gate::allows('isAdmin')) { echo 'Admin user role is allowed'; } else { echo 'Admin are not allowed not allowed'; } } /** * Example 2 * @return 403 Error */ public function index() { $this->authorize('isAdmin'); // return 403 }
Use Gate in Blade Template
Laravel provides an easy way to use gates in the blade template. If we want to display a portion of the page when the user is authorized to perform a given action. Here, you can use the “@can” and “@cannot” directives.
@can('isAdmin') <h2>Admin View</h2> @elsecan('isEditor') <h2>Editor View</h2> @else <h2>Guest View</h2> @endcan
Conclusion
In this article, we are discussing the Laravel Authorization with Gates. I’m trying to explain the Laravel Gates in a simple and easy way. Hope you like this article, feel free to add your comments if any query. You can submit your feedback too. In our next post, we will discuss Laravel Authorization with Policies and many more.
You may like:
Laravel Default Authentication Setup
How to Use Make Auth in Laravel 6
If you like our content, please consider buying us a coffee.
Thank you for your support!
Buy Me a Coffee
Hi, if the route can be access by admin and an editor, I’m trying this but it’s not working, like
middleware(‘can:isAdmin, isEditor’)
Can you help ?
middleware supports array, so use:
middleware([‘can:isAdmin’, ‘can:isEditor’])
Hi 🙂
// Admin Only
Route::middleware(‘can:isAdmin’)->prefix(‘admin’)->group(function () {
// Mention all admin routes
Route::get(‘/’, ‘AdminController@index’);
});
is not working.
It works only if you write
Route::middleware(‘can:isAdmin’)->group(function () {
// Mention all admin routes
Route::get(‘/’, ‘AdminController@index’);
});