14 β Avtorizatsiya (Gates va Policies)¶
β¬ οΈ Oldingi: 13 β Autentifikatsiya Β· π README Β· Keyingi: 15 β Middleware β‘οΈ
Bu bobda: tizimga kirgan foydalanuvchi HAR amalni qila olmasligini β ya'ni avtorizatsiyani (authorization, "nimaga ruxsating bor?") o'rganamiz. Avval uni autentifikatsiyadan (authentication, "kimsan?") ajratamiz. Keyin oddiy bir martalik huquqlar uchun
Gateni (Gate::define,Gate::allows/denies), model amallari uchunPolicyni (make:policy --model,viewAny/view/create/update/deletemetodlari) ko'rib chiqamiz. ControllerdaGate::authorize(), helpercan(), Blade'da@can,before()hook (admin hammasini qiladi), resource policy + resource controller, owner-based (faqat egasi) ruxsat va rollar bilan oddiy yondashuvni (oxiridaspatie/laravel-permissionga qisqa ishora) o'rganamiz.
Muammo¶
13-bobda foydalanuvchini tizimga kiritdik: endi auth()->user() bizga kim so'rov yuborganini aytadi. Lekin bu hali yetarli emas. Blogimizda Aziz ham, Malika ham ro'yxatdan o'tgan. Aziz manzil qatoriga /posts/7/edit deb yozadi β bu Malika yozgan post. Hozircha controllerimiz hech narsani tekshirmaydi:
// PostController β hali himoyasiz
public function update(Request $request, Post $post)
{
$post->update($request->validate([
'title' => 'required|string|max:255',
'body' => 'required|string',
]));
return redirect()->route('posts.show', $post);
}
Aziz tizimga kirgan β demak auth middleware (15-bob) uni o'tkazib yuboradi. Va u Malikaning postini bemalol tahrirlab qo'yadi. Bu β jiddiy xavfsizlik teshigi. Kirgan bo'lish (login qilgan) hamma narsaga ruxsat degani emas. Kerakli qoida sodda: "postni faqat egasi tahrirlasin".
Bu ikki xil savol:
- Authentication (autentifikatsiya): "Sen kimsan?" β email va parol bilan kimligingni isbotlaysan. Buni 13-bobda qildik.
- Authorization (avtorizatsiya): "Nima qila olasan?" β kim ekaning aniqlangach, aynan shu amalga (bu postni tahrirlashga) ruxsating bor-yo'qligini tekshiramiz. Shu bobning mavzusi.
π Ikki atamani aralashtirmaslik uchun: authn (n β name, kimsan) va authz (z β ...orize, ruxsat) deb qisqartirishadi. Avval doim authn, keyin authz: noma'lum odamning huquqini tekshirib bo'lmaydi.
Laravel avtorizatsiya uchun ikkita asbob beradi:
- Gate β bitta, modelga bog'liq bo'lmagan huquq uchun ("admin panelni ko'rish"). Yopiq closure.
- Policy β bitta model atrofidagi barcha amallar uchun ("postni ko'rish/yaratish/tahrirlash/o'chirish"). Alohida klass.
Aralashib ketmaslik uchun oddiy qoida: bitta model + uning amallari β Policy; modelsiz yoki bir martalik tekshiruv β Gate. Avval soddaroq Gate'dan boshlaymiz.
Gate β bir martalik huquq¶
Gate (so'zma-so'z "darvoza") β bu nomlangan ruxsat tekshiruvi. Uni odatda App\Providers\AppServiceProviderning boot() metodida e'lon qilamiz. boot() β ilova ishga tushganda bir marta chaqiriladigan joy (2-bobdan tanish).
// app/Providers/AppServiceProvider.php
namespace App\Providers;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Gate::define('admin-panelni-korish', function (User $user) {
return $user->role === 'admin';
});
}
}
Gate::define('nom', closure) β birinchi argument huquq nomi (string), ikkinchisi β true/false qaytaradigan closure. Closure'ning birinchi parametri doim joriy foydalanuvchi (User $user) β Laravel uni avtomatik uzatadi. Endi istalgan joyda shu nom bilan so'raymiz:
use Illuminate\Support\Facades\Gate;
if (Gate::allows('admin-panelni-korish')) {
// ruxsat bor β davom etamiz
}
if (Gate::denies('admin-panelni-korish')) {
// ruxsat yo'q β to'xtatamiz
}
allows β "ruxsat beradimi?" (true bo'lsa ha), denies β uning aksi. Ikkalasiga ham Userni qo'lda berishimiz shart emas: Gate joriy kirgan foydalanuvchini o'zi oladi.
Controllerda ko'p hollarda taqiqlanganda darrov 403 qaytaramiz:
// app/Http/Controllers/AdminController.php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Gate;
class AdminController extends Controller
{
public function index()
{
if (Gate::denies('admin-panelni-korish')) {
abort(403);
}
return view('admin.index');
}
}
abort(403) β so'rovni darrov to'xtatib, "403 Forbidden" (taqiqlangan) javobini qaytaradi. 404 ("topilmadi") emas: bu yerda sahifa bor, lekin senga yopiq.
π‘ User modelida role ustuni bor deb faraz qilyapmiz. Migratsiyada $table->string('role')->default('user'); qo'shib, User modelining $fillableiga 'role'ni kiritib qo'ying. 7- va 8-boblardan eslang.
π Gate closure'ining birinchi parametri ixtiyoriy bo'lishi mumkin emas deb o'ylamang β agar tekshiruv mehmon (login qilmagan) uchun ham ishlashi kerak bo'lsa, ?User $user (nullable) qiling. Aks holda mehmonga Gate avtomatik false qaytaradi va closure umuman chaqirilmaydi.
before Gate bilan: super-admin¶
Ba'zan bitta odam (egasi/super-admin) hamma darvozadan o'tishi kerak. Har bir Gate ichida buni qayta yozish o'rniga, bitta global Gate::before yozamiz:
Gate::before(function (User $user, string $ability) {
if ($user->role === 'super-admin') {
return true; // hamma tekshiruvdan o'tkazamiz
}
return null; // hech narsa hal qilmadik -> oddiy Gate ishlaydi
});
π Diqqat: null qaytarish β "men qaror qabul qilmayman, davom et" degani. Agar false qaytarsangiz, ENG MUHIM xato bo'ladi: hamma tekshiruvni darrov rad etib qo'yasiz. "Qarorsizlik" uchun doim null.
Gate yetmaganda β Policy¶
Gate bitta huquq uchun yaxshi. Lekin Post atrofida amallar ko'p: ko'rish, ro'yxatni ko'rish, yaratish, tahrirlash, o'chirish. Bularning hammasini alohida Gate qilsak, AppServiceProvider shishib ketadi va mantiq tarqalib qoladi. Policy β bitta model bilan bog'liq barcha avtorizatsiya qoidalarini bitta klassga yig'adi.
Policy yaratamiz β --model bayrog'i bilan, shunda Laravel barcha standart metodlarni tayyor skelet qilib beradi:
Bu app/Policies/PostPolicy.php faylini quyidagicha yaratadi (skeletni o'z qoidalarimiz bilan to'ldiramiz):
// app/Policies/PostPolicy.php
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
class PostPolicy
{
// Postlar RO'YXATINI ko'rish (index)
public function viewAny(User $user): bool
{
return true; // har kim ro'yxatni ko'ra oladi
}
// BITTA postni ko'rish (show)
public function view(User $user, Post $post): bool
{
return true;
}
// Yangi post YARATISH (create/store)
public function create(User $user): bool
{
return true; // kirgan har kim yoza oladi
}
// Postni TAHRIRLASH (edit/update) β faqat egasi
public function update(User $user, Post $post): bool
{
return $post->user_id === $user->id;
}
// Postni O'CHIRISH (destroy) β faqat egasi
public function delete(User $user, Post $post): bool
{
return $post->user_id === $user->id;
}
}
Mana shu β muammoning yechimi. update va delete metodlari postning user_idsini joriy foydalanuvchining idsi bilan solishtiradi. Bir xil bo'lsa β egasi, true. Bo'lmasa β begona, false. Bu owner-based (egasiga asoslangan) avtorizatsiya.
Metodlarning nomlanishida mantiq bor:
| Controller amali | Policy metodi | Argumentlar |
|---|---|---|
index (ro'yxat) |
viewAny |
faqat User |
show (bitta) |
view |
User + Post |
create / store |
create |
faqat User |
edit / update |
update |
User + Post |
destroy |
delete |
User + Post |
π viewAny va create metodlariga Post obyekt berilmaydi β chunki bu amallar muayyan postga emas, umuman postlarga tegishli. ("Yaratishdan oldin qaysi post?" degan savol mantiqsiz.) Qolgan uchtasi aniq bir post bilan ishlaydi, shuning uchun ikkinchi argument oladi.
π Laravel 11+ da policy'lar avtomatik topiladi (auto-discovery): App\Models\Post modeli uchun App\Policies\PostPolicy klassi o'z-o'zidan ulanadi β qo'lda ro'yxatga olish kerak emas. Agar nom konvensiyaga sig'masa (masalan policy boshqa joyda tursa), Gate::policy(Post::class, PostPolicy::class) bilan o'zingiz bog'laysiz.
Policy'ni controllerda chaqirish β Gate::authorize()¶
Endi himoyasiz updateimizni mustahkamlaymiz. Controllerda Gate::authorize('amal', $model) deymiz: ruxsat bo'lsa kod davom etadi, bo'lmasa Laravel avtomatik 403ni tashlaydi β qo'lda abort yozish shart emas.
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class PostController extends Controller
{
public function index()
{
Gate::authorize('viewAny', Post::class);
return view('posts.index', ['posts' => Post::all()]);
}
public function edit(Post $post)
{
Gate::authorize('update', $post);
return view('posts.edit', ['post' => $post]);
}
public function update(Request $request, Post $post)
{
Gate::authorize('update', $post); // <-- himoya shu yerda
$post->update($request->validate([
'title' => 'required|string|max:255',
'body' => 'required|string',
]));
return redirect()->route('posts.show', $post);
}
public function destroy(Post $post)
{
Gate::authorize('delete', $post);
$post->delete();
return redirect()->route('posts.index');
}
}
Gate::authorize('update', $post)ni Laravel shunday o'qiydi: "$post β Post modeli; demak PostPolicy::update metodini joriy User va shu $post bilan chaqir". Agar metod true qaytarsa β kod ipdan o'tadi; false qaytarsa β so'rov 403 bilan to'xtaydi va updatening qolgan qatorlari umuman ishlamaydi.
π viewAny va create kabi modelsiz amallarda obyekt emas, klass nomini beramiz: Gate::authorize('viewAny', Post::class). Laravel klass nomidan qaysi policy ekanini tushunadi, lekin metodga $post uzatmaydi (chunki yo'q).
π Laravel 11+ da bazaviy App\Http\Controllers\Controller klassi bo'sh β unda hech qanday trait yo'q. Shuning uchun eski qo'llanmalardagi $this->authorize('update', $post) shaklini ishlatsangiz, "Call to undefined method ...::authorize()" xatosini olasiz. Zamonaviy, ishlaydigan yo'l β yuqoridagidek Gate facade'ini ishlatish (use Illuminate\Support\Facades\Gate;). Agar baribir $this->authorize() qisqaroq shaklini xohlasangiz, bazaviy controllerga qo'lda use Illuminate\Foundation\Auth\Access\AuthorizesRequests; trait'ini qo'shishingiz kerak β lekin Gate::authorize() hech qanday qo'shimchasiz ishlaydi va rasmiy hujjatlar aynan shuni tavsiya qiladi.
Boshqa shakllar: can() va cannot()¶
authorize() taqiqlanganda darrov 403 tashlaydi β ko'pincha aynan shu kerak. Lekin ba'zan natijani tekshirib, o'zimiz qaror qilmoqchimiz. Buning uchun foydalanuvchidagi can()/cannot() helperlari bor:
$post = Post::find(1);
if (auth()->user()->can('update', $post)) {
// egasi β tahrir tugmasini ko'rsatamiz
}
if (request()->user()->cannot('update', $post)) {
abort(403); // o'zimiz xohlagan reaksiya
}
// Gate facade orqali ham (User'ni o'zi oladi):
use Illuminate\Support\Facades\Gate;
if (Gate::allows('update', $post)) {
// ...
}
β
$user->can('update', $post) β Policy'ni ham, Gate'ni ham bir xil chaqiradi. Laravel argumentga qarab o'zi hal qiladi: $post β model, demak Policy; oddiy string β Gate.
β if ($post->user_id == auth()->id()) deb tekshiruvni controller bo'ylab sochib yubormang. Bugun bitta joyda, ertaga o'nta joyda β biri esdan chiqsa teshik ochiladi. Mantiqni Policy'ga jamlang, controllerda faqat authorize/can deb chaqiring.
Blade'da @can β tugmani ko'rsatish/yashirish¶
Avtorizatsiya faqat backend'da emas, ko'rinishda ham kerak. Begona postda "Tahrirlash" tugmasini ko'rsatishning ma'nosi yo'q β bossayam baribir 403 oladi. @can direktivasi shu tugmani faqat ruxsati borlarga ko'rsatadi:
{{-- resources/views/posts/show.blade.php --}}
<article>
<h1>{{ $post->title }}</h1>
<p>{{ $post->body }}</p>
@can('update', $post)
<a href="{{ route('posts.edit', $post) }}">Tahrirlash</a>
@endcan
@can('delete', $post)
<form method="POST" action="{{ route('posts.destroy', $post) }}">
@csrf
@method('DELETE')
<button>O'chirish</button>
</form>
@endcan
</article>
@can('update', $post) ... @endcan orasidagi HTML faqat Policy true qaytarganda chiqadi. Egasi tugmani ko'radi, begona β yo'q. @cannot esa aksini beradi:
@can ichida @else ham bor, hamda bir nechta huquqdan birortasini tekshiradigan @canany:
@can('update', $post)
<a href="{{ route('posts.edit', $post) }}">Tahrirlash</a>
@else
<span>Faqat ko'rish mumkin</span>
@endcan
@canany(['update', 'delete'], $post)
<div class="boshqaruv-paneli">...</div>
@endcanany
π MUHIM tuzoq: @can faqat ko'rinishni boshqaradi β u xavfsizlik chorasi EMAS. Tugmani yashirsangiz ham, ayyor foydalanuvchi to'g'ridan-to'g'ri PUT /posts/7 so'rovini yuborishi mumkin. Shuning uchun @can controllerdagi authorize()ni almashtirmaydi, balki to'ldiradi. Haqiqiy himoya β har doim backend'da. @can β shunchaki foydalanuvchiga keraksiz tugmani ko'rsatmaslik.
before() hook β admin hammasini qiladi¶
Sayt o'sib, admin paydo bo'ldi. Admin har kimning postini tahrirlashi va o'chirishi kerak. Hozir update/delete faqat egasiga true beradi β admin o'tolmaydi. Har metodga || $user->role === 'admin' qo'shish β takror va xatoga moyil. Policy ichidagi before() metodi buni bir joyda hal qiladi: u boshqa har qanday metoddan oldin chaqiriladi.
// app/Policies/PostPolicy.php
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
class PostPolicy
{
// Boshqa hamma metoddan OLDIN ishlaydi
public function before(User $user, string $ability): ?bool
{
if ($user->role === 'admin') {
return true; // admin -> hamma amalga ruxsat
}
return null; // admin emas -> oddiy metodlar hal qilsin
}
public function update(User $user, Post $post): bool
{
return $post->user_id === $user->id;
}
public function delete(User $user, Post $post): bool
{
return $post->user_id === $user->id;
}
}
before uch xil javob beradi:
trueβ "ruxsat", qolgan metodlar chaqirilmaydi (admin o'tib ketdi);falseβ "qat'iy taqiq", metodlar chaqirilmaydi (masalan bloklangan user);nullβ "men hal qilmayman", odatdagi metod (update,delete...) o'z ishini qiladi.
π ENG KO'P UCHRAYDIGAN XATO: admin emas degan holatda false qaytarish. Unda admin bo'lmagan HECH KIM hech narsa qila olmaydi β egasi ham o'z postiga kira olmaydi, chunki before darrov false bilan to'xtatib qo'yadi. "Bu yerda qaror yo'q" uchun doim null qaytaring, false emas.
π‘ Yuqorida pure-PHP'da tekshirib ko'rdik: Aziz o'z postiga true, Malika begona postga false, admin esa egasidan qat'i nazar before() orqali true oladi β aynan kutilgan xulq.
Resource controllerni himoyalash β can middleware¶
4-bobda Route::resource bilan 7 ta CRUD route'ni bir qatorda yaratgandik. Endi har metodga qo'lda Gate::authorize yozish o'rniga, himoyani route darajasida can middleware bilan ulashimiz mumkin β Policy'ni controllerga umuman tegmasdan:
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
Route::put('/posts/{post}', [PostController::class, 'update'])
->middleware('can:update,post');
Route::delete('/posts/{post}', [PostController::class, 'destroy'])
->middleware('can:delete,post');
can:update,post β "shu route'ga kirishdan oldin update huquqini {post} route parametri ustida tekshir". So'rov controllerga yetishidan oldin PostPolicy::update chaqiriladi; ruxsat bo'lmasa 403. Middleware haqida to'liq 15-bobda gaplashamiz.
π Laravel 11+ tuzog'i: eski qo'llanmalarda controller konstruktorida $this->authorizeResource(Post::class, 'post') uchraydi. U endi to'g'ridan-to'g'ri ishlamaydi β Laravel 11+ da bazaviy Controller klassi bo'sh va konstruktorda middleware ulashning ($this->middleware()) o'zi yo'q. Shuning uchun zamonaviy, ishlaydigan yo'l β yo yuqoridagidek route can middleware, yo har metodda Gate::authorize() (yuqorida ko'rdik). Ikkalasi ham hech qanday qo'shimcha trait yoki sozlama talab qilmaydi.
Rollar bilan oddiy yondashuv¶
Hozirgacha owner-based (egasi) edik. Lekin ko'p loyihada rollar kerak: admin, muharrir, oddiy. Eng sodda yo'l β users jadvaliga bitta role ustuni qo'shish va User modeliga kichik yordamchilar yozish:
// app/Models/User.php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $fillable = ['name', 'email', 'password', 'role'];
public function isAdmin(): bool
{
return $this->role === 'admin';
}
public function hasRole(string $role): bool
{
return $this->role === $role;
}
}
Endi Gate yoki Policy ichida shu metodlarni ishlatamiz:
Gate::define('postni-tasdiqlash', function (User $user) {
return $user->hasRole('muharrir') || $user->isAdmin();
});
β Kichik loyiha (2-3 rol, oddiy qoidalar) uchun bu yetarli va tushunarli.
β Lekin loyiha o'ssa β role ustuni tor bo'lib qoladi: bitta user bir nechta rolga ega bo'lsa-chi? Yoki rolsiz, alohida huquq ("faqat shu bo'limni boshqarish") kerak bo'lsa-chi? Stringli role buni ko'tara olmaydi.
π‘ Bunday holatda velosipedni qaytadan ixtiro qilmang. spatie/laravel-permission paketi β Laravel olamida rol/huquqlar uchun de-fakto standart. U roles va permissions jadvallarini, ko'p-ko'pga munosabatlarni (9-bob) va $user->hasRole('admin'), $user->can('postlarni-tahrirlash'), @role, @hasanyrole kabi qulay helperlarni tayyor beradi. O'rnatish bir buyruq:
Eng yaxshisi β uning huquqlarini ham Policy ichidan ishlating: nazorat baribir bitta joyda (Policy'da) qoladi, faqat "egasimi?" o'rniga "shu huquq bormi?" deb so'raysiz. Shunda kichik loyihadan kattasiga o'tish silliq kechadi.
Hammasini birga β yakuniy manzara¶
Endi bobni bitta jumlaga jamlaylik. Foydalanuvchi /posts/7/editga so'rov yuboradi:
- auth middleware (15-bob) tekshiradi: kirib bo'lganmi? Yo'q bo'lsa β login sahifasiga.
- Controller
editmetodiGate::authorize('update', $post)deydi. - Laravel
PostPolicy::update($user, $post)ni chaqiradi. - Avval
before()ishlaydi: admin bo'lsa β darrovtrue. - Admin bo'lmasa β
update()"egasimi?"ni tekshiradi. trueβ sahifa ochiladi;falseβ403 Forbidden.
Asosiy qoidalar:
- authn β authz. Kirgan bo'lish hamma narsaga ruxsat degani emas.
- Mantiqni jamla. Tekshiruvni controller bo'ylab sochmang β Gate yoki Policy'ga yig'ing.
@canβ bezak,authorizeβ qalqon. Tugmani yashirish himoya emas; haqiqiy nazorat backend'da.beforedanull. "Qaror yo'q" uchunfalseemas,nullqaytaring.- Bitta model β Policy, bir martalik β Gate.
14-bob mashqlari¶
π‘ Mashqlarni 8-9-boblardagi blog loyihangizda (User, Post, Comment modellari) bajaring. Kerak bo'lsa users jadvaliga role ustunini va posts jadvaliga user_id (egasi) ustunini qo'shing.
AppServiceProviderningboot()metodidaGate::define('admin-panelni-korish', ...)e'lon qiling: faqatrole === 'admin'bo'lgan usergatrue.tinkerdaGate::forUser($user)->allows('admin-panelni-korish')bilan ikki xil user uchun tekshiring.AdminController@indexyarating va boshidaGate::denies(...)bo'lsaabort(403)qiling. Brauzerda oddiy va admin user bilan kirib, farqni ko'ring.- Bitta sahifada
@can('admin-panelni-korish')bilan "Admin panel" havolasini faqat adminlarga ko'rsating. Gate::beforeyozing:role === 'super-admin'bo'lgan user HAMMA gate'dan o'tsin. "Qarorsizlik" uchunnullqaytarishni unutmang.php artisan make:policy PostPolicy --model=Postbilan policy yarating. Metodlar ro'yxatini ko'rib chiqing.PostPolicy::updateni shunday yozing: faqat post egasi ($post->user_id === $user->id) tahrirlay olsin.deleteni ham xuddi shunday.PostController@updategaGate::authorize('update', $post)qo'shing (use Illuminate\Support\Facades\Gate;). Egasi bo'lmagan user bilan tahrir qilib ko'ring β403olishingiz kerak.PostController@editva@destroyga ham mosauthorizechaqiruvlarini qo'shing.posts/show.blade.phpda "Tahrirlash" tugmasini@can('update', $post)ichiga oling. Begona post sahifasida tugma yo'qolishini tasdiqlang.- Xuddi shu sahifada
@can('delete', $post)bilan "O'chirish" formasini (@method('DELETE')) yashiring/ko'rsating. @elseishlatib: egasiga "Tahrirlash" havolasini, boshqalarga "Faqat ko'rish" matnini chiqaring.viewAnymetodini yozing (har kim ro'yxatni ko'radi) vaPostController@indexdaGate::authorize('viewAny', Post::class)bilan klass nomini berib chaqiring (obyekt emas).PostPolicygabefore()qo'shing:role === 'admin'bo'lsatrue, aks holdanull. Admin har kimning postini tahrirlay olishini tekshiring.before()da ataylabnullo'rnigafalseqaytarib ko'ring: endi egasi ham o'z postiga kira olmasligini kuzating, keyinnullga qaytaring va nega shunday bo'lganini izohlang.can()helper bilan controllerdaif (auth()->user()->cannot('update', $post)) { abort(403); }shaklini yozing βauthorize()siz xuddi shu natijaga erishing.Commentmodeli uchunCommentPolicyyarating: izohni faqat yozgan user o'chira olsin (delete), lekin post egasi ham o'chira olsin (ikki shartdan biri).- Eski qo'llanmalarda uchraydigan
$this->authorizeResource(Post::class, 'post')konstruktorda Laravel 11+ da nega ishlamasligini (393-qatorga qarang: bazaviyControllerbo'sh, konstruktorda$this->middleware()yo'q) bir izoh bilan yozing. Keyin resource route'larni routecanmiddleware bilan himoyalang:updateroute'iga->middleware('can:update,post'),destroyga->middleware('can:delete,post'). Har metoddagi alohidaauthorizechaqiruvlarini olib tashlab, himoya baribir ishlashini tekshiring. - Route faylida
updateroute'ini->middleware('can:update,post')bilan himoyalang β controllerga tegmasdan. Begona user bilan403olinishini tasdiqlang. UsermodeligaisAdmin()vahasRole(string $role)metodlarini qo'shing vaGate::define('postni-tasdiqlash', ...)ichida muharrir yoki admin tekshiruvini ular orqali yozing.php artisan tinkerda: ikkita user va bitta post yarating;Gate::forUser($egasi)->allows('update', $post)vaGate::forUser($begona)->allows('update', $post)natijalarini solishtiring β birinchisitrue, ikkinchisifalsechiqishi kerak.