نسخه:

مجوز

معرفی

لاراول علاوه بر ارائه خدمات احراز هویت داخلی ، راه ساده ای را نیز برای مجوز دادن به اقدامات کاربر در برابر یک منبع مشخص ارائه می دهد. به عنوان مثال، حتی اگر یک کاربر احراز هویت شده باشد، ممکن است مجاز به به روز رسانی یا حذف برخی از مدل های Eloquent یا رکوردهای پایگاه داده مدیریت شده توسط برنامه شما نباشد. ویژگی های مجوز لاراول روشی آسان و سازمان یافته برای مدیریت این نوع بررسی های مجوز ارائه می دهد.

لاراول دو راه اصلی برای مجوز فعالیت ها ارائه می دهد: دروازه ها و سیاست ها . به دروازه ها و سیاست هایی مانند مسیرها و کنترلرها فکر کنید. گیت ها یک رویکرد ساده و مبتنی بر بسته شدن برای مجوز ارائه می کنند در حالی که سیاست ها، مانند کنترل کننده ها، منطق را حول یک مدل یا منبع خاص گروه بندی می کنند. در این مستندات، ابتدا گیت ها را بررسی می کنیم و سپس سیاست ها را بررسی می کنیم.

شما نیازی به انتخاب بین استفاده انحصاری از گیت ها یا استفاده انحصاری از سیاست ها در هنگام ساختن یک برنامه ندارید. اکثر برنامه ها به احتمال زیاد حاوی ترکیبی از گیت ها و سیاست ها هستند، و این کاملاً خوب است! گیت ها برای اقداماتی که به هیچ مدل یا منبعی مرتبط نیستند، مانند مشاهده داشبورد سرپرست، بیشتر کاربرد دارند. در مقابل، زمانی که می‌خواهید برای یک مدل یا منبع خاص مجوز انجام دهید، باید از خط‌مشی‌ها استفاده شود.

دروازه ها

نوشتن گیتس

گیت ها یک راه عالی برای یادگیری اصول اولیه ویژگی های مجوز لاراول هستند. با این حال، هنگام ساخت برنامه های لاراول قوی، باید از سیاست هایی برای سازماندهی قوانین مجوز خود استفاده کنید.

گیت ها به سادگی بسته هایی هستند که تعیین می کنند آیا کاربر مجاز به انجام یک عمل خاص است یا خیر. به طور معمول، دروازه ها در boot روش کلاس App\Providers\AppServiceProvider با استفاده از Gate نما تعریف می شوند. گیت ها همیشه یک نمونه کاربر را به عنوان اولین آرگومان دریافت می کنند و ممکن است به صورت اختیاری آرگومان های اضافی مانند مدل Eloquent مربوطه را دریافت کنند.

در این مثال، یک گیت تعریف می کنیم تا مشخص کنیم که آیا کاربر می تواند یک App\Models\Post مدل مشخص را به روز کند یا خیر. گیت این کار را با مقایسه کاربر id با user_id کاربر ایجاد کننده پست انجام می دهد:

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Gate::define('update-post', function (User $user, Post $post) {
return $user->id === $post->user_id;
});
}

مانند کنترل‌کننده‌ها، گیت‌ها نیز ممکن است با استفاده از یک آرایه برگشت کلاس تعریف شوند:

use App\Policies\PostPolicy;
use Illuminate\Support\Facades\Gate;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Gate::define('update-post', [PostPolicy::class, 'update']);
}

اعمال مجوز

برای مجاز کردن یک اقدام با استفاده از گیت ها، باید از allows یا denies روش های ارائه شده توسط Gate نما استفاده کنید. توجه داشته باشید که لازم نیست کاربر تأیید شده فعلی را به این روش ها منتقل کنید. لاراول به طور خودکار از عبور دادن کاربر به داخل گیت مراقبت می کند. معمولاً قبل از انجام عملی که نیاز به مجوز دارد، متدهای مجوز گیت را در کنترلرهای برنامه خود فراخوانی کنید:

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
 
class PostController extends Controller
{
/**
* Update the given post.
*/
public function update(Request $request, Post $post): RedirectResponse
{
if (! Gate::allows('update-post', $post)) {
abort(403);
}
 
// Update the post...
 
return redirect('/posts');
}
}

اگر می خواهید تعیین کنید که آیا کاربری غیر از کاربر تأیید شده فعلی مجاز به انجام یک عمل است، می توانید از روش forUser روی Gate نما استفاده کنید:

if (Gate::forUser($user)->allows('update-post', $post)) {
// The user can update the post...
}
 
if (Gate::forUser($user)->denies('update-post', $post)) {
// The user can't update the post...
}

می‌توانید همزمان چندین اقدام را با استفاده از روش‌های any زیر مجاز کنید none :

if (Gate::any(['update-post', 'delete-post'], $post)) {
// The user can update or delete the post...
}
 
if (Gate::none(['update-post', 'delete-post'], $post)) {
// The user can't update or delete the post...
}

مجوز یا پرتاب استثناها

اگر می‌خواهید اقدامی را مجاز کنید و Illuminate\Auth\Access\AuthorizationException اگر کاربر مجاز به انجام آن عمل نباشد، به طور خودکار یک علامت را پرتاب کنید، می‌توانید از روش Gate نما استفاده کنید authorize . نمونه های AuthorizationException به طور خودکار توسط لاراول به یک پاسخ HTTP 403 تبدیل می شوند:

Gate::authorize('update-post', $post);
 
// The action is authorized...

ارائه متن اضافی

متدهای گیت برای تأیید توانایی ها ( ،،،،،،،،،، allows ) و دستورالعمل های Blade مجوز ( ،،، ) می توانند یک آرایه را به عنوان آرگومان دوم خود دریافت کنند denies . این عناصر آرایه به‌عنوان پارامترهایی به بسته شدن دروازه ارسال می‌شوند و می‌توانند برای زمینه اضافی هنگام تصمیم‌گیری مجوز استفاده شوند: check any none authorize can cannot @can @cannot @canany

use App\Models\Category;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
 
Gate::define('create-post', function (User $user, Category $category, bool $pinned) {
if (! $user->canPublishToGroup($category->group)) {
return false;
} elseif ($pinned && ! $user->canPinPosts()) {
return false;
}
 
return true;
});
 
if (Gate::check('create-post', [$category, $pinned])) {
// The user can create the post...
}

پاسخ های گیت

تا اینجا ما فقط گیت هایی را بررسی کرده ایم که مقادیر ساده بولی را برمی گرداند. با این حال، گاهی اوقات ممکن است بخواهید پاسخ دقیق تری، از جمله یک پیام خطا، بازگردانید. برای انجام این کار، می توانید یک عدد Illuminate\Auth\Access\Response از دروازه خود را برگردانید:

use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
 
Gate::define('edit-settings', function (User $user) {
return $user->isAdmin
? Response::allow()
: Response::deny('You must be an administrator.');
});

حتی زمانی که یک پاسخ مجوز را از گیت خود برمی گردانید، Gate::allows روش همچنان یک مقدار بولی ساده را برمی گرداند. با این حال، می توانید از Gate::inspect روش برای دریافت پاسخ مجوز کامل توسط گیت استفاده کنید:

$response = Gate::inspect('edit-settings');
 
if ($response->allowed()) {
// The action is authorized...
} else {
echo $response->message();
}

هنگام استفاده از Gate::authorize روشی که AuthorizationException در صورت عدم مجاز بودن اقدام، یک علامت را می اندازد، پیام خطای ارائه شده توسط پاسخ مجوز به پاسخ HTTP منتشر می شود:

Gate::authorize('edit-settings');
 
// The action is authorized...

سفارشی کردن وضعیت پاسخ HTTP

هنگامی که یک عمل از طریق یک دروازه رد می شود، یک 403 پاسخ HTTP برگردانده می شود. با این حال، گاهی اوقات بازگرداندن کد وضعیت HTTP جایگزین می تواند مفید باشد. می‌توانید کد وضعیت HTTP را که برای بررسی مجوز ناموفق بازگردانده شده است، با استفاده از denyWithStatus سازنده استاتیک در Illuminate\Auth\Access\Response کلاس سفارشی کنید:

use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
 
Gate::define('edit-settings', function (User $user) {
return $user->isAdmin
? Response::allow()
: Response::denyWithStatus(404);
});

از آنجایی که پنهان کردن منابع از طریق یک 404 پاسخ یک الگوی رایج برای برنامه های کاربردی وب است، این denyAsNotFound روش برای راحتی ارائه شده است:

use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
 
Gate::define('edit-settings', function (User $user) {
return $user->isAdmin
? Response::allow()
: Response::denyAsNotFound();
});

رهگیری چک های دروازه

گاهی اوقات، ممکن است بخواهید تمام توانایی ها را به یک کاربر خاص اعطا کنید. می‌توانید از این before روش برای تعریف بستنی استفاده کنید که قبل از سایر بررسی‌های مجوز اجرا می‌شود:

use App\Models\User;
use Illuminate\Support\Facades\Gate;
 
Gate::before(function (User $user, string $ability) {
if ($user->isAdministrator()) {
return true;
}
});

اگر before بسته شدن یک نتیجه غیر تهی برگرداند، آن نتیجه نتیجه بررسی مجوز در نظر گرفته می شود.

می‌توانید از این after روش برای تعریف بسته‌بندی استفاده کنید که باید پس از بررسی‌های دیگر مجوز اجرا شود:

use App\Models\User;
 
Gate::after(function (User $user, string $ability, bool|null $result, mixed $arguments) {
if ($user->isAdministrator()) {
return true;
}
});

مشابه before روش، اگر after بسته شدن یک نتیجه غیر تهی را برگرداند، آن نتیجه نتیجه بررسی مجوز در نظر گرفته می شود.

مجوز درون خطی

گاهی اوقات، ممکن است بخواهید تعیین کنید که آیا کاربر تأیید شده در حال حاضر مجاز به انجام یک عمل معین بدون نوشتن یک گیت اختصاصی مطابق با آن عمل است یا خیر. لاراول به شما اجازه می دهد تا این نوع بررسی های مجوز "داخلی" را از طریق متدهای Gate::allowIf و انجام دهید Gate::denyIf . مجوز درون خطی هیچ قلاب مجوز تعریف شده "قبل" یا "بعد" را اجرا نمی کند :

use App\Models\User;
use Illuminate\Support\Facades\Gate;
 
Gate::allowIf(fn (User $user) => $user->isAdministrator());
 
Gate::denyIf(fn (User $user) => $user->banned());

اگر اکشن مجاز نباشد یا در حال حاضر هیچ کاربری احراز هویت نشده باشد، لاراول به طور خودکار یک Illuminate\Auth\Access\AuthorizationException استثنا ایجاد می کند. نمونه های AuthorizationException به طور خودکار توسط کنترل کننده استثنایی لاراول به پاسخ HTTP 403 تبدیل می شوند.

ایجاد سیاست ها

ایجاد سیاست ها

سیاست ها کلاس هایی هستند که منطق مجوز را حول یک مدل یا منبع خاص سازماندهی می کنند. به عنوان مثال، اگر برنامه شما یک وبلاگ است، ممکن است یک App\Models\Post مدل و یک مدل متناظر App\Policies\PostPolicy برای مجاز کردن اقدامات کاربر مانند ایجاد یا به‌روزرسانی پست‌ها داشته باشید.

می توانید با استفاده از make:policy دستور Artisan یک خط مشی ایجاد کنید. خط مشی ایجاد شده در app/Policies دایرکتوری قرار می گیرد. اگر این دایرکتوری در برنامه شما وجود نداشته باشد، لاراول آن را برای شما ایجاد می کند:

php artisan make:policy PostPolicy

این make:policy دستور یک کلاس سیاست خالی ایجاد می کند. اگر می‌خواهید یک کلاس با روش‌های خط‌مشی مثال مربوط به مشاهده، ایجاد، به‌روزرسانی و حذف منبع ایجاد کنید، می‌توانید --model هنگام اجرای دستور، گزینه‌ای را ارائه کنید:

php artisan make:policy PostPolicy --model=Post

سیاست های ثبت نام

کشف سیاست

به‌طور پیش‌فرض، لاراول به‌طور خودکار سیاست‌ها را کشف می‌کند تا زمانی که مدل و خط‌مشی از قراردادهای نام‌گذاری استاندارد لاراول پیروی کنند. به طور خاص، خط مشی ها باید در Policies دایرکتوری در دایرکتوری یا بالاتر از دایرکتوری حاوی مدل های شما باشند. بنابراین، برای مثال، مدل‌ها ممکن است در app/Models فهرست قرار گیرند، در حالی که سیاست‌ها ممکن است در app/Policies فهرست قرار گیرند. در این شرایط، لاراول سیاست‌های app/Models/Policies موجود را بررسی می‌کند app/Policies . علاوه بر این، نام خط مشی باید با نام مدل مطابقت داشته باشد و دارای Policy پسوند باشد. بنابراین، یک مدل با یک کلاس سیاست User مطابقت دارد . UserPolicy

اگر می‌خواهید منطق کشف خط‌مشی خود را تعریف کنید، می‌توانید با استفاده از Gate::guessPolicyNamesUsing روش، یک پاسخ تماس کشف خط مشی سفارشی ثبت کنید. به طور معمول، این متد باید از boot روش برنامه شما فراخوانی شود AppServiceProvider :

use Illuminate\Support\Facades\Gate;
 
Gate::guessPolicyNamesUsing(function (string $modelClass) {
// Return the name of the policy class for the given model...
});

ثبت نام دستی خط مشی ها

با استفاده از Gate نما، می توانید به صورت دستی خط مشی ها و مدل های مربوط به آنها را در boot روش برنامه خود ثبت کنید AppServiceProvider :

use App\Models\Order;
use App\Policies\OrderPolicy;
use Illuminate\Support\Facades\Gate;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Gate::policy(Order::class, OrderPolicy::class);
}

سیاست های نوشتن

روش های سیاست گذاری

هنگامی که کلاس خط مشی ثبت شد، می توانید روش هایی را برای هر اقدامی که مجوز می دهد اضافه کنید. به عنوان مثال، بیایید update روشی را در خود تعریف کنیم PostPolicy که تعیین می کند آیا یک داده می تواند یک نمونه App\Models\User معین را به روز کند یا خیر . App\Models\Post

این متد یک و یک نمونه را به عنوان آرگومان های خود update دریافت می کند و باید برگردد یا نشان دهد که آیا کاربر مجاز به به روز رسانی داده شده است یا خیر . بنابراین، در این مثال، بررسی می کنیم که کاربر با پست مطابقت دارد : User Post true false Post id user_id

<?php
 
namespace App\Policies;
 
use App\Models\Post;
use App\Models\User;
 
class PostPolicy
{
/**
* Determine if the given post can be updated by the user.
*/
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
}

می‌توانید به تعریف روش‌های اضافی روی خط‌مشی در صورت نیاز برای اقدامات مختلفی که مجوز می‌دهد، ادامه دهید. برای مثال، ممکن است روش‌هایی را برای مجوز فعالیت‌های مرتبط مختلف تعریف کنید view ، delete اما Post به یاد داشته باشید که می‌توانید هر نامی را که دوست دارید به روش‌های خط‌مشی خود بدهید.

اگر --model هنگام ایجاد خط‌مشی خود از طریق کنسول Artisan از این گزینه استفاده کرده‌اید، از قبل حاوی روش‌هایی برای viewAny , view , create , update , delete , restore و forceDelete اقدامات است.

تمام خط مشی ها از طریق کانتینر سرویس لاراول حل می شوند و به شما این امکان را می دهند که هر وابستگی مورد نیاز را در سازنده خط مشی تایپ کنید تا به طور خودکار آنها را تزریق کنید.

پاسخ های خط مشی

تا کنون، ما فقط روش‌های سیاستی را بررسی کرده‌ایم که مقادیر بولی ساده را برمی‌گردانند. با این حال، گاهی اوقات ممکن است بخواهید پاسخ دقیق تری، از جمله یک پیام خطا، بازگردانید. برای انجام این کار، می توانید یک Illuminate\Auth\Access\Response نمونه از روش سیاست خود را برگردانید:

use App\Models\Post;
use App\Models\User;
use Illuminate\Auth\Access\Response;
 
/**
* Determine if the given post can be updated by the user.
*/
public function update(User $user, Post $post): Response
{
return $user->id === $post->user_id
? Response::allow()
: Response::deny('You do not own this post.');
}

هنگام برگرداندن پاسخ مجوز از خط مشی شما، Gate::allows روش همچنان یک مقدار بولی ساده را برمی گرداند. با این حال، می توانید از Gate::inspect روش برای دریافت پاسخ مجوز کامل توسط گیت استفاده کنید:

use Illuminate\Support\Facades\Gate;
 
$response = Gate::inspect('update', $post);
 
if ($response->allowed()) {
// The action is authorized...
} else {
echo $response->message();
}

هنگام استفاده از Gate::authorize روشی که AuthorizationException در صورت عدم مجاز بودن اقدام، یک علامت را می اندازد، پیام خطای ارائه شده توسط پاسخ مجوز به پاسخ HTTP منتشر می شود:

Gate::authorize('update', $post);
 
// The action is authorized...

سفارشی کردن وضعیت پاسخ HTTP

هنگامی که یک عمل از طریق یک روش سیاست رد می شود، یک 403 پاسخ HTTP برگردانده می شود. با این حال، گاهی اوقات بازگرداندن کد وضعیت HTTP جایگزین می تواند مفید باشد. می‌توانید کد وضعیت HTTP را که برای بررسی مجوز ناموفق بازگردانده شده است، با استفاده از denyWithStatus سازنده استاتیک در Illuminate\Auth\Access\Response کلاس سفارشی کنید:

use App\Models\Post;
use App\Models\User;
use Illuminate\Auth\Access\Response;
 
/**
* Determine if the given post can be updated by the user.
*/
public function update(User $user, Post $post): Response
{
return $user->id === $post->user_id
? Response::allow()
: Response::denyWithStatus(404);
}

از آنجایی که پنهان کردن منابع از طریق یک 404 پاسخ یک الگوی رایج برای برنامه های کاربردی وب است، این denyAsNotFound روش برای راحتی ارائه شده است:

use App\Models\Post;
use App\Models\User;
use Illuminate\Auth\Access\Response;
 
/**
* Determine if the given post can be updated by the user.
*/
public function update(User $user, Post $post): Response
{
return $user->id === $post->user_id
? Response::allow()
: Response::denyAsNotFound();
}

روش‌های بدون مدل

برخی از روش‌های خط‌مشی فقط نمونه‌ای از کاربر تأیید شده فعلی را دریافت می‌کنند. این وضعیت در هنگام مجوز دادن به اقدامات رایج است create . به عنوان مثال، اگر در حال ایجاد یک وبلاگ هستید، ممکن است بخواهید تعیین کنید که آیا کاربر اصلاً مجاز به ایجاد هرگونه پست است یا خیر. در این شرایط، روش خط مشی شما فقط باید انتظار دریافت یک نمونه کاربر را داشته باشد:

/**
* Determine if the given user can create posts.
*/
public function create(User $user): bool
{
return $user->role == 'writer';
}

کاربران مهمان

به‌طور پیش‌فرض، false اگر درخواست HTTP دریافتی توسط کاربر احراز هویت شده آغاز نشده باشد، همه گیت‌ها و خط‌مشی‌ها به‌طور خودکار برمی‌گردند. با این حال، می‌توانید با اعلام یک نوع اشاره «اختیاری» یا ارائه یک null مقدار پیش‌فرض برای تعریف آرگومان کاربر، اجازه دهید این بررسی‌های مجوز به گیت‌ها و خط‌مشی‌های شما منتقل شوند :

<?php
 
namespace App\Policies;
 
use App\Models\Post;
use App\Models\User;
 
class PostPolicy
{
/**
* Determine if the given post can be updated by the user.
*/
public function update(?User $user, Post $post): bool
{
return $user?->id === $post->user_id;
}
}

فیلترهای خط مشی

برای کاربران خاصی، ممکن است بخواهید همه اقدامات را در یک خط مشی مشخص مجاز کنید. برای انجام این کار، before روشی را روی خط مشی تعریف کنید. این before متد قبل از هر روش دیگری در خط مشی اجرا می شود و به شما فرصتی می دهد تا قبل از فراخوانی روش سیاست مورد نظر، اقدام را مجاز کنید. این ویژگی بیشتر برای اجازه دادن به مدیران برنامه برای انجام هر عملی استفاده می شود:

use App\Models\User;
 
/**
* Perform pre-authorization checks.
*/
public function before(User $user, string $ability): bool|null
{
if ($user->isAdministrator()) {
return true;
}
 
return null;
}

اگر می‌خواهید همه بررسی‌های مجوز برای نوع خاصی از کاربر را رد کنید، می‌توانید false از before روش برگردید. اگر null بازگردانده شود، بررسی مجوز از طریق روش سیاست قرار می گیرد.

before اگر کلاس حاوی متدی با نامی مطابق با نام توانایی در حال بررسی نباشد، متد یک کلاس سیاست فراخوانی نخواهد شد .

مجوز اقدامات با استفاده از خط مشی ها

از طریق مدل کاربر

مدلی App\Models\User که در برنامه لاراول شما گنجانده شده است شامل دو روش مفید برای مجوز دادن به اقدامات است: can و cannot . و متدها نام اقدامی را که می‌خواهید مجاز کنید و مدل مربوطه را دریافت می‌کنند can . cannot به عنوان مثال، اجازه دهید تعیین کنیم که آیا کاربر مجاز به به روز رسانی یک App\Models\Post مدل خاص است یا خیر. به طور معمول، این در یک روش کنترلر انجام می شود:

<?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 post.
*/
public function update(Request $request, Post $post): RedirectResponse
{
if ($request->user()->cannot('update', $post)) {
abort(403);
}
 
// Update the post...
 
return redirect('/posts');
}
}

اگر یک خط مشی برای مدل داده شده ثبت شود can ، متد به طور خودکار خط مشی مناسب را فراخوانی می کند و نتیجه بولی را برمی گرداند. اگر هیچ خط مشی برای مدل ثبت نشده باشد، این can روش سعی می کند دروازه مبتنی بر بسته شدن را که با نام عمل داده شده مطابقت دارد فراخوانی کند.

اقداماتی که به مدل نیاز ندارند

به یاد داشته باشید، برخی از اقدامات ممکن است با روش های خط مشی مطابقت داشته باشند، مانند create روش هایی که نیازی به نمونه مدل ندارند. در این مواقع، می توانید نام کلاس را به can متد ارسال کنید. از نام کلاس برای تعیین اینکه از کدام خط مشی هنگام مجوز دادن به عملکرد استفاده شود استفاده می شود:

<?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
{
/**
* Create a post.
*/
public function store(Request $request): RedirectResponse
{
if ($request->user()->cannot('create', Post::class)) {
abort(403);
}
 
// Create the post...
 
return redirect('/posts');
}
}

از طریق Gate نما

علاوه بر روش‌های مفید ارائه‌شده به App\Models\User مدل، همیشه می‌توانید از طریق روش Gate نما ، اعمال را مجاز کنید authorize .

مانند can متد، این روش نیز نام اقدامی را که می‌خواهید مجاز کنید و مدل مربوطه را می‌پذیرد. اگر اقدام مجاز نباشد، authorize متد یک استثنا ایجاد می کند Illuminate\Auth\Access\AuthorizationException که کنترل کننده استثنای لاراول به طور خودکار به یک پاسخ HTTP با کد وضعیت 403 تبدیل می کند:

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
 
class PostController extends Controller
{
/**
* Update the given blog post.
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request, Post $post): RedirectResponse
{
Gate::authorize('update', $post);
 
// The current user can update the blog post...
 
return redirect('/posts');
}
}

اقداماتی که به مدل نیاز ندارند

همانطور که قبلاً بحث شد، برخی از روش‌های خط‌مشی مانند create نیازی به نمونه مدل ندارند. در این مواقع باید یک نام کلاس به authorize متد ارسال کنید. از نام کلاس برای تعیین اینکه از کدام خط مشی هنگام مجوز دادن به عملکرد استفاده شود استفاده می شود:

use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
 
/**
* Create a new blog post.
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function create(Request $request): RedirectResponse
{
Gate::authorize('create', Post::class);
 
// The current user can create blog posts...
 
return redirect('/posts');
}

از طریق Middleware

لاراول شامل یک میان افزار است که می تواند اقدامات را قبل از اینکه درخواست ورودی حتی به مسیرها یا کنترلرهای شما برسد مجوز دهد. به‌طور پیش‌فرض، میان‌افزار ممکن است با استفاده از نام مستعار میان‌افزار Illuminate\Auth\Middleware\Authorize به مسیری متصل شود که به‌طور خودکار توسط لاراول ثبت می‌شود. بیایید نمونه‌ای از استفاده از میان‌افزار برای اجازه دادن به کاربر برای به‌روزرسانی یک پست را بررسی کنیم: can can

use App\Models\Post;
 
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,post');

در این مثال، ما can دو آرگومان میان افزار را ارسال می کنیم. اولی نام اقدامی است که می‌خواهیم مجوز دهیم و دومی پارامتر مسیری است که می‌خواهیم به متد Policy منتقل کنیم. در این حالت، از آنجایی که از binding مدل ضمنی استفاده می کنیم ، یک App\Models\Post مدل به روش Policy منتقل می شود. اگر کاربر مجاز به انجام عمل داده شده نباشد، یک پاسخ HTTP با کد وضعیت 403 توسط میان افزار برگردانده می شود.

برای راحتی، همچنین می توانید can میان افزار را با استفاده از روش زیر به مسیر خود متصل کنید can :

use App\Models\Post;
 
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->can('update', 'post');

اقداماتی که به مدل نیاز ندارند

باز هم، برخی از روش‌های سیاست مانند create نیازی به نمونه مدل ندارند. در این مواقع، ممکن است نام کلاس را به میان افزار منتقل کنید. از نام کلاس برای تعیین اینکه از کدام خط مشی هنگام مجوز دادن به عملکرد استفاده شود استفاده می شود:

Route::post('/post', function () {
// The current user may create posts...
})->middleware('can:create,App\Models\Post');

تعیین نام کل کلاس در تعریف میان افزار رشته ای می تواند دست و پا گیر شود. به همین دلیل، می توانید can با استفاده از روش زیر، میان افزار را به مسیر خود متصل کنید can :

use App\Models\Post;
 
Route::post('/post', function () {
// The current user may create posts...
})->can('create', Post::class);

از طریق قالب های Blade

هنگام نوشتن الگوهای Blade، ممکن است بخواهید بخشی از صفحه را تنها در صورتی نمایش دهید که کاربر مجاز به انجام یک عمل خاص باشد. به عنوان مثال، ممکن است بخواهید یک فرم به روز رسانی برای یک پست وبلاگ را تنها در صورتی نشان دهید که کاربر واقعا بتواند پست را به روز کند. در این شرایط، می توانید از دستورات @can و استفاده کنید @cannot :

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

این دستورالعمل ها میانبرهای مناسبی برای نوشتن @if و @unless بیانیه ها هستند. عبارات @can و @cannot جملات فوق معادل عبارات زیر است:

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

همچنین می‌توانید تعیین کنید که آیا کاربر مجاز به انجام هر عملی از یک آرایه معین از اقدامات است یا خیر. برای انجام این کار، از @canany دستورالعمل استفاده کنید:

@canany(['update', 'view', 'delete'], $post)
<!-- The current user can update, view, or delete the post... -->
@elsecanany(['create'], \App\Models\Post::class)
<!-- The current user can create a post... -->
@endcanany

اقداماتی که به مدل نیاز ندارند

مانند بسیاری از روش‌های مجوزدهی دیگر، اگر عمل به نمونه‌ای از مدل نیاز نداشته باشد، می‌توانید نام کلاس را به دستورالعمل‌ها @can و دستورالعمل‌ها ارسال کنید: @cannot

@can('create', App\Models\Post::class)
<!-- The current user can create posts... -->
@endcan
 
@cannot('create', App\Models\Post::class)
<!-- The current user can't create posts... -->
@endcannot

ارائه متن اضافی

هنگام مجوز دادن به اقدامات با استفاده از خط‌مشی‌ها، می‌توانید یک آرایه را به‌عنوان آرگومان دوم به توابع و کمک‌کننده‌های مختلف مجوز ارسال کنید. اولین عنصر در آرایه برای تعیین اینکه کدام خط مشی باید فراخوانی شود استفاده می شود، در حالی که بقیه عناصر آرایه به عنوان پارامتر به روش خط مشی ارسال می شوند و می توانند برای زمینه اضافی در هنگام تصمیم گیری مجوز استفاده شوند. به عنوان مثال، تعریف روش زیر را در نظر بگیرید که حاوی یک پارامتر PostPolicy اضافی است : $category

/**
* Determine if the given post can be updated by the user.
*/
public function update(User $user, Post $post, int $category): bool
{
return $user->id === $post->user_id &&
$user->canUpdateCategory($category);
}

هنگام تلاش برای تعیین اینکه آیا کاربر تأیید شده می تواند یک پست داده شده را به روز کند یا خیر، می توانیم این روش خط مشی را به این صورت فراخوانی کنیم:

/**
* Update the given blog post.
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request, Post $post): RedirectResponse
{
Gate::authorize('update', [$post, $request->category]);
 
// The current user can update the blog post...
 
return redirect('/posts');
}