NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Permissions for Laravel

Gate a middleware

Pri zapnutom register_gate_check (predvolene) sa oprávnenia vyhodnocujú cez Gate v Laraveli, takže natívny middleware can: funguje hneď:

Route::get('/users', UsersController::class)->middleware('can:auth.users.view');

$user->can('auth.users.view');           // true when granted directly or via a role
Gate::forUser($user)->allows('auth.users.view');

Ako hook rozhoduje

Balík zaregistruje jediný hook Gate::before. Odpovedá iba vtedy, keď platí všetko nasledujúce — inak vráti null a vaše vlastné gates a policies prebehnú bez zásahu:

  • Kontrola nemá argumenty — žiadny model ani ďalšie parametre — alebo pri zapnutých priradeniach práve jeden PermissionScope (pozrite Kontroly v rozsahu nižšie).
  • Model používateľa má metódu hasPermissionTo(), teda používa HasRoles.
  • Ability je názov zaregistrovaného oprávnenia.

Ak používateľ oprávnenie drží — priamo alebo cez rolu — hook vráti true. Nikdy nevráti false: používateľ bez oprávnenia prejde na vaše gates, a ak žiadne nie sú, Laravel prístup zamietne, takže middleware can: odpovie kódom 403.

Posledné slovo majú policies

Kontrola oprávnení nikdy neprebije policy modelu. Hneď ako kontrola nesie model alebo akýkoľvek argument — $user->can('update', $post) či middleware can:update,post — hook prenechá rozhodnutie vašej gate alebo policy. Oprávnenie s názvom update autorizuje $user->can('update'), no o $user->can('update', $post) stále rozhoduje PostPolicy::update():

Permissions::permission('update');
Permissions::for($user)->givePermissionTo('update');

$user->can('update');          // true — argument-less, answered by the permission
$user->can('update', $post);   // PostPolicy::update() decides — ownership, tenancy, …
final class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $post->owner_id === $user->getKey();
    }
}

Hrubozrnné oprávnenia a policies viazané na model tak fungujú vedľa seba a ani jedno potichu nepohltí druhé.

Kontroly v rozsahu

Pri zapnutých priradeniach odovzdajte Permissions::scope() ako jediný argument pre Gate a kontrola prebehne v rámci projektu, tímu či tenanta — viac rozsahov znamená ktorýkoľvek z nich. Funguje s can(), Gate::authorize() aj @can; nové Blade direktívy nepribudli:

use RoundlyConsulting\Permissions\Facades\Permissions;

$user->can('posts.edit', Permissions::scope($project));
Gate::authorize('posts.edit', Permissions::scope([$team, $parentTeam])); // any of them
@can('posts.edit', Permissions::scope($project))
    <button>Edit post</button>
@endcan

Hook stále odpovedá len true alebo null, takže vaše gates môžu prístup ešte povoliť. Na PermissionScope sa nemôže naviazať žiadna policy, takže kontrola v rozsahu s ňou nikdy nekoliduje; akýkoľvek iný tvar argumentov ide nedotknutý k vašim gates a policies.

Implicitný rozsah

Kontroly bez rozsahu — middleware can:, @can('posts.edit'), $user->can('posts.edit') — zostávajú bez rozsahu, takže ich priradenie v rozsahu nikdy nesplní. Zaregistrujte resolver, ktorý im dodá implicitný rozsah, napríklad aktuálny tím či projekt:

// app/Providers/AppServiceProvider.php → boot()
use Illuminate\Contracts\Auth\Access\Authorizable;
use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Permissions\Facades\Permissions;

Permissions::resolveScopeUsing(
    fn (Authorizable $user, string $ability): Model|iterable|null => $user->currentProject,
);

// can:posts.edit, @can('posts.edit') and $user->can('posts.edit') now check inside it
Permissions::resolveScopeUsing(null); // remove it again

Ak resolver vráti null alebo prázdny zoznam, kontrola zostane bez rozsahu. Resolver platí len pre Gate, nikdy pre hasPermissionTo() či hasRole(), a žije v singletone v kontajneri, takže ho Permissions::fake() zachová. teams-for-laravel si pri zapnutom moste k permissions zaregistruje jeden pre aktuálny tím.

Middleware pre routy s rozsahom

EnsurePermission overí oprávnenie v rozsahu, na ktorý je naviazaný parameter routy. Alias sa neregistruje — odkazujte na triedu:

use RoundlyConsulting\Permissions\Http\Middleware\EnsurePermission;

Route::put('/projects/{project}/posts/{post}', UpdatePost::class)
    ->middleware(EnsurePermission::using('posts.edit', scope: 'project'));

// the same, as a string
Route::put('/projects/{project}/posts/{post}', UpdatePost::class)
    ->middleware(EnsurePermission::class.':posts.edit,project');

// unscoped
Route::get('/admin', AdminController::class)
    ->middleware(EnsurePermission::using('admin.access'));

Parameter rozsahu musí byť implicitne naviazaný model; chýbajúci alebo nenaviazaný vyhodí PermissionException — je to chyba routy, nikdy tiché povolenie či zamietnutie. Neprihlásený používateľ, používateľ bez HasRoles alebo chýbajúce oprávnenie skončí výnimkou AuthorizationException (403). Middleware sa pýta priamo registra, nie Gate, takže funguje aj pri vypnutom register_gate_check a ignoruje resolveScopeUsing() — na to použite middleware can:.

Vypnutie hooku

Nastavte register_gate_check na false, ak chcete hook úplne vynechať — vrátane kontrol v rozsahu — a oprávnenia vyhodnocovať sami:

// config/permissions.php
'register_gate_check' => false,

// then check explicitly where you need it
abort_unless($request->user()->hasPermissionTo('auth.users.view'), 403);

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.