Think of gates and policies like routes and controllers. Gates provide a simple, Closure based approach to authorization while policies, like controllers, group their logic around a particular model or resource. We’ll explore gates first and then examine policies.
Writing Gates
Gates are Closures that determine if a user is authorized to perform a given action and are typically defined in the class App\Providers\AuthServiceProvider
using the facade Gate. Gates always receive a user instance as their first argument and may optionally receive additional arguments such as a relevant Eloquent model.
Laravel Gates
Laravel Gates and Policies restrict the users based on their logic. Gates may also be defined using a Class@method
style callback string, like controllers.
Let’s take an example to understand Gates. Laravel provides the user table’s migration by default, so what we will do is make one more column called isAdmin and set the datatype to the boolean.
/** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); Gate::define('update-post', 'PostPolicy@update'); }
Step 1: Install Laravel And Setup Database.
composer create-project laravel/laravel --prefer-dist gates
Now, set up the database in a .env file.
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=gates DB_USERNAME=root DB_PASSWORD=
We need to change the user migration file and add one more column called isAdmin as a boolean.
/** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->boolean('isAdmin')->default(0); $table->string('email')->unique(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); }
Now, migrate the database.
php artisan migrate
Step 2: Make auth system.
In your root, type the following command in your terminal.
php artisan make:auth
It will create the register and login system for us. Now, register the three users for the sample.
Now, go to the table and change any of the user’s isAdmin values to 1. This is an example, so we manually do it; otherwise, we must change it to 1 programmatically.
So, we will write the gates logic for a user who is the admin. Otherwise, some resources will not be displayed to the logged-in user if he is not an admin.
Now, go to the resources >> views >> welcome.blade.php. Add the following line to the code.
@if (Route::has('login')) <div class="top-right links"> @auth <a href="{{ url('/home') }}">Home</a> <a href="{{ url('/private') }}">Private</a> @else <a href="{{ route('login') }}">Login</a> <a href="{{ route('register') }}">Register</a> @endauth </div> @endif
Also, define the route in the routes >> web.php file.
Route::get('/privare', 'HomeController@private')->name('private');
/** * Show the application private resources. * * @return \Illuminate\Http\Response */ public function private() { return view('private'); }
Now, create a private.blade.php file.
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading">Private Resources</div> <div class="panel-body"> Confidential Information </div> </div> </div> </div> </div> @endsection
Now, log in to the application and go to the http://localhost:8000
You can see another navigation item called Private. Right now, you can see this thing, and you can navigate to that page. But we need to prevent viewing this page that is not an admin. That is why Gates comes into the play.
Step 3: Define the Gates.
Go to the app >> providers >> AuthServiceProvider.php file and define the gate.
/** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); Gate::define('admin-only', function ($user) { if($user->isAdmin == 1) { return true; } return false; }); }
Okay, the remaining step is to tell the application that this route is protected by the admin.
So in the HomeController file, write the following code.
use Illuminate\Support\Facades\Gate; /** * Show the application private resources. * * @return \Illuminate\Http\Response */ public function private() { if (Gate::allows('admin-only', auth()->user())) { return view('private'); } return 'You are not admin!!!!'; }
So, when you logged in as a user whose isAdmin is one then, you can view the private resources, otherwise not. The next step is to do not display private navigation items to the non-admin user because it makes no sense to show them the secret part at all.
In the welcome.blade.php file, you can add the @can directive.
@if (Route::has('login')) <div class="top-right links"> @auth <a href="{{ url('/home') }}">Home</a> @can('admin-only', auth()->user()) <a href="{{ url('/private') }}">Private</a> @endcan @else <a href="{{ route('login') }}">Login</a> <a href="{{ route('register') }}">Register</a> @endauth </div> @endif
Now, only the admin can see the Private view of the application. So we have used Gate as an authorized user to show only resources that the user has been allowed. There is one more concept called Policy, which we will see in the next tutorial. You can explore more API in Laravel’s documentation.
That is it for this tutorial.
Kind of obvoius, and im pretty sure you also know this, but when making examples like this, use good names!
Like, “can: admin-only”, sure, it might work, but i’d say “can: go-to-private” is a better name in this case.
Also when defining the gate, a single-liner would be perfect there, like “return $user->isAdmin == 1 (true|false)”.
Nice article tho, keep it up!
You may also want to take a look at :
http://www.github.com/imanghafoori1/laravel-heyman
to aid you in using laravel gates
great tutorial . thnx
super dude,… really very helpfull
this is very useful for me.
thank you
Thanks, Chief, I had implemented gates but didn’t add the auth()->user(), because the tutorial I was using did not. you just saved my weekend Chief.