Laravel policies are a powerful feature for handling authorization logic in a Laravel application. They provide a clean, organized way to manage who can do what with various resources (such as models) in your app. Let's walk through an example to illustrate how you can use policies to control access to a Post model in a blog application.
Generate a policy for the Post model using the Artisan command:
php artisan make:policy PostPolicy --model=Post
Check here we have used model name + policy as policy name. You don't need to register or bind the policy with model and Laravel automatically does that for you when we do that.
<?php
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class PostPolicy
{
use HandlesAuthorization;
....
// Allow only the author of the post to update it
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
With this we can allow only the author of the post to update it. And here is how we can use it inside PostController.
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
// Update logic here
}
Now let us add multiple conditions. Let us add a logic to disable edits after an hour of post creation
public function update(User $user, Post $post)
{
// First, check if the user is the author of the post
if ($user->id !== $post->user_id) {
return false;
}
// Then, check if more than an hour has passed since the post was created
$oneHourAfterPostCreation = $post->created_at->addHours(1);
return now()->lessThan($oneHourAfterPostCreation);
}
Here’s what this code does:
It first checks if the logged-in user is the author of the post. If not, it immediately returns false, denying the update permission.
If the user is the author, it calculates the time one hour after the post was created ($oneHourAfterPostCreation) by adding one hour to the post's created_at timestamp.
Then, it checks if the current time (now()) is before (lessThan) the $oneHourAfterPostCreation. If it is, the function returns true, allowing the edit; otherwise, it returns false, preventing the edit.
In Laravel policies, you can encapsulate multiple authorization logics within a single method to create sophisticated and nuanced access controls tailored to your application's needs.
And here is another advantage. We can add this easily inside a resource and send it to frontend
PostResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class PostResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'user' => $this->whenLoaded('user', fn () => UserResource::make($this->user)),
'title' => $this->title,
'body' => $this->body,
'updated_at' => $this->updated_at,
'created_at' => $this->created_at,
'can' => [
'update' => $request->user()?->can('update', $this->resource),
],
];
}
}
This resource includes a can array that uses Laravel's authorization features to dynamically add permissions related to the post. For example, it checks if the authenticated user has the permission to 'update' the post. This is done by calling $request->user()?->can('update', $this->resource), which evaluates to true or false based on the policies defined for the Post model. This technique seamlessly integrates Laravel's powerful authorization system into your API's responses, enabling the client-side application to easily understand and respect the permissions of the authenticated user.
Top comments (0)