Policies — Laravel 10 Discovery Training
In this new chapter, we will dive back into the security part and we will see Laravel’s authorization system. Until now we have simply used the middleware system but it is possible to use classes which will allow to define the permissions action by action.
The creation of an access policy will often be done in connection with a model.
php artisan make:policy PostPolicy --model=Post
Then inside the file PostPolicy
functions should return false
Or true
depending on whether or not access to the resource is authorized. It will then be necessary to save the link between the model and the policy by modifying the property $policies
in the AuthServiceProvider
.
<?php
namespace App\Providers;
use App\Models\Post;
use App\Policies\PostPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
Post::class => PostPolicy::class,
];
public function boot(): void
{
// ...
}
}
Check permission
Now that our policies are created we can use them to check whether or not the user has access to a resource. This can be done in different ways.
Model User
The model User
provides by default has methods to verify user access.
$user->can('update', $post); // true / false
$user->cannot('update', $post); // true /false
Controller
If your Controller inherits the App\Http\Controllers\Controller
you will have access to the method authorize
which will allow you to see if the user has the right to do the requested action.
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class PostController extends Controller
{
/**
* Update the given blog post.
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request, Post $post): RedirectResponse
{
$this->authorize('update', $post);
return redirect('/posts');
}
}
This method will throw an exception if the user does not have the necessary permissions and the framework will catch it to act accordingly (redirection or display of a JSON response).
Middleware
Laravel also offers special middleware can
which allows permission to be checked from the route declaration.
use App\Models\Post;
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,post');
Blade
In blade views if you want to show or hide a button depending on user permissions you can use the directive @can
Or @cannot
.
@can('update', $post)
<!-- L'utilisateur peut modifier l'article... -->
@elsecan('create', App\Models\Post::class)
<!-- L'utilisateur peut créer un article... -->
@else
<!-- ... -->
@endcan
@cannot('update', $post)
<!-- L'utilisateur ne peut pas modifier l'article... -->
@elsecannot('create', App\Models\Post::class)
<!-- ... -->
@endcannot