مجوز
معرفی
لاراول علاوه بر ارائه خدمات احراز هویت داخلی ، راه ساده ای را نیز برای مجوز دادن به اقدامات کاربر در برابر یک منبع مشخص ارائه می دهد. به عنوان مثال، حتی اگر یک کاربر احراز هویت شده باشد، ممکن است مجاز به به روز رسانی یا حذف برخی از مدل های 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');}