Laravel Policies – Controlling Authorization in Laravel

Laravel Policies Controlling Authorization in Laravel

Spread the word! Share with your fellow developers.

Laravel Policies are a great way to protect actions on your Eloquent Model. Laravel Policies are the part of Laravel Authorization that helps you to protect resources from unauthorized access.

In this post, I will show you how you can create a Laravel Policy to protect actions on your model. You might be familiar with Laravel Policies, this post is intended to help new users of Laravel.

What is Laravel Policy?

Laravel Policy is a class, where you can organize the authorization logic of your application. For example, you might have a blog application built in Laravel and want to protect that only users who own the blog post can delete it. In this post, I will show you how you can achieve this.

Basic Setup

For this post, I assume you have a Laravel application set up. Firstly you need to update database credentials, in .env file like below.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=blog
DB_USERNAME=root
DB_PASSWORD=

Next we have to create model, migration and controller for users and posts. Laravel installtion comes with User model and migration so we will create only Post model and migration.

Run below command in terminal to generate, model and migration for Post.

php artisan make:model Post -m

Open you post’s migration file and add below:

Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('content');
            $table->boolen('status');
            $table->integer('user_id');
            $table->timestamps();
        });

Once you have your migration ready, run php artisan migrate to create users and posts table in the database.

If everything works fine for you, you will able to see two tables in your database called users and posts. Now create some users and posts in database tables. You can make a seed or add them manually.

Create Policy

Laravel provides an artisan command to generate a policy. Run below command to generate a policy which will be created in the folder app/Policies.

php artisan make:policy PostPolicy

Note

It’s always recommended to create policy prefix with the model name. In out case it was Post model, so we created PostPolicy.

If you want to generate all CRUD methods within the policy you can run below command.

php artisan make:policy PostPolicy --model=Post

The first command will create below class.

namespace App\Policies;

use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;

class PostPolicy
{
    use HandlesAuthorization;

    /**
     * Create a new policy instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
}

Adding Logic to Policy

Now we have generated our policy, its time to add our logic to this policy. We want to allow delete method only to users who have created a post. For example, if we have a user with id 3, and our one of post belong to this user by using user_id column, we want to allow to delete this post by the only user with id 3.

We will create a new method called delete() as we want to restrict delete action, like below.

public function delete(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }

This method will check whether the post creator is this user or not and return true or false.

Registering Policy

Once we have updated our policy logic, it’s time to register this policy. Open AuthServicProvider file from app/Providers.

Add your PostPolicy to the $policies array like below.

namespace App\Providers;

use App\Post;
use App\Policies\PostPolicy;
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',
        Post::class => PostPolicy::class,
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        //
    }
}

Using Policy in Views

Once you have followed all the above steps, now you can use this policy in the views. You can use the @can and @cannot blade directive to check the policy.

For example,

@can('delete', $post)
  // show post delete button
@endcan
@cannot('delete', $post)
  // disable post delete button
@endcannot

It’s up to you which directive you want to use depending on your application.

Using Policy in Model

You can also use the policy in your Post model. You can use the below code to check if the Post is deletable for the current user in any of model’s method.

if ($user->can('delete', $post)) {
  // add your actions here
}

Using Policy in Controller

Now we will use the same policy in our PostController to authorize the delete functionality like so:

public function delete(Post $post)
{
  $this->authorize('delete', $post);
  // The current user can delete the post
}

Laravel policies provide extra control on the authorization. You can use the polices to create a full fledge permissions management system which will make your whole application controllable and add extra security to your application.

If you have any question or suggestion, please leave them in the comments box below.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

*
*

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