Laravel Policy using Spatie Roles & Permission Tutorial step by step

By Ved Prakash N | Feb 27, 2024 | Laravel
Share : Whatsapp

https://www.fundaofwebit.com/post/laravel-policy-using-spatie-roles-and-permission-tutorial-step-by-step

Laravel Policy Tutorial using Spatie Roles & Permission step by step


In this post, you will learn how to create and use Laravel 10 Policies (Laravel Authorization) with Spatie Roles and Permissions step by step tutorial. 

So let's get started:


Step 1: Create a Policy using the artisan command

php artisan make:policy CategoryPolicy


Step 2: Register the Policy in AuthServiceProvider file - path: app/Providers/AuthServiceProvider.php file

add the created policy in the $policies property

protected $policies = [
    Category::class => CategoryPolicy::class
    // ...
];


Step 3: Define Policy Methods in your created CategoryPolicy.php file - path : app/ Policies/ CategoryPolicy.php

<?php

namespace App\Policies;

use App\Models\Category;
use App\Models\User;
use Illuminate\Auth\Access\Response;

class CategoryPolicy
{
    public function before(User $user): bool|null
    {
        if($user->hasRole(['super-admin'])){
            return true;
        }

        return null;
    }

    public function viewAny(User $user): bool
    {
        return true;
    }

    public function view(User $user, Category $category): bool
    {
        if($user->hasPermissionTo('view categoy')){
            return true;
        }else{
            return false;
        }
    }

    public function create(User $user): bool
    {
        if($user->hasPermissionTo('create categoy')){
            return true;
        }else{
            return false;
        }
    }

    public function update(User $user, Category $category): bool
    {
        if($user->hasPermissionTo('update categoy')){
            return true;
        }else{
            return false;
        }
    }

    public function delete(User $user, Category $category): bool
    {
        if($user->hasPermissionTo('delete categoy')){
            return true;
        }else{
            return false;
        }
    }
}


Step 4: Use Policy in the Controller

$this->authorize() method:

<?php

namespace App\Http\Controllers;

use App\Models\Category;
use Illuminate\Http\Request;

class CategoryController extends Controller
{
    public function index()
    {
        $this->authorize('viewAny', new Category());
        //...
    }

    public function create()
    {
        $this->authorize('create', Category::class);
        //...
    }

    public function store(Request $request)
    {
        $this->authorize('create', Category::class);
        //...
    }

    public function show(Category $category)
    {
        $this->authorize('view', $category);
        //...
    }

    public function edit(Category $category)
    {
        $this->authorize('update', $category);
        //...
    }

    public function update(Request $request, Category $category)
    {
        $this->authorize('update', $category);
        //...
    }

    public function destroy(Category $category)
    {
        $this->authorize('delete', $category);
        //...
    }
}


"can" and "cannot" methods used in controller:

Example for "Cannot" :

public function store(Request $request)
{
    if ($request->user()->cannot('create', Category::class)) {
        abort(403);
    }
    //...
}

public function update(Request $request, Category $category)
{
    if ($request->user()->cannot('update', $category)) {
        abort(403);
    }
    //...
}


Example for "Can" :

public function store(Request $request)
{
    if (Auth::user()->can('create', Category::class)) {

        //... your code
    }else{
        abort(403);
    }
}

public function update(Request $request, Category $category)
{
    if (Auth::user()->can('update', $category)) {

        //... your code
    }else{
        abort(403);
    }
}


Step 5: Use Policy in Blade files

@can is a shortcut of @if condition

@can('update', $category)
    <!-- The current user can update the post... -->
@elsecan('create', App\Models\Category::class)
    <!-- The current user can create new posts... -->
@else
    <!-- ... -->
@endcan
@can('create', App\Models\Category::class)
    <!-- The current user can create posts... -->
@endcan


@cannot is a shortcut of @unless condition

@cannot('update', $category)
    <!-- The current user cannot update the post... -->
@elsecannot('create', App\Models\Category::class)
    <!-- The current user cannot create new posts... -->
@endcannot
@cannot('create', App\Models\Category::class)
    <!-- The current user can't create posts... -->
@endcannot


Instead of @can & @unless how can use in this way:

@if (Auth::user()->can('update', $category))
    <!-- The current user can update the post... -->
@endif
@unless (Auth::user()->can('update', $category))
    <!-- The current user cannot update the post... -->
@endunless


That's it.
Thanks for reading.