Laravel Gates Tutorial: What You Need to Know

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.

gates in laravel 5.5

 

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.

See also

Laravel Docker Container

Laravel Form Validation

6 thoughts on “Laravel Gates Tutorial: What You Need to Know”

  1. 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!

    Reply
  2. 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.

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.