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.