Despre laravel gates si policies

Laravel | Stefanescu Mihai | 2024-01-12

In acest articol o sa vorbim despre gates si policies. In laravel, ca in orice alt framework web trebuie sa fim atenti la partea de securitate si autorizare. 

Ce este un Gate in Laravel?


Un gate este o functie ce defineste un set de permisiuni pentru o resursa data. Un gate este folosit pentru a determina daca un anumit user are permisiunea de a accesa o anumita actiune. In-un gate acest lucru are forma unei functii ce intoarce un boolean ce spune daca user-ula re voie sau nu sa faca actiunea dorita.

Hai sa vedem un exemplu, in care definim un gate in App\Providers\AuthServiceProvider:

Gate::define('edit-post', function (User $user, Post $post) {        
    return $user->id === $post->user_id;    
});


Iar apoi, din controll-erul in care vremsa facem aceasta verificare putem apela:

class PostController extends Controller
{
    public function update(Request $request, Post $post): RedirectResponse
    {
        if (! Gate::allows('edit-post', $post)) {
            abort(403);
        }
 
        // logica de business pentru actiunea data...
    }
}


 Ce este un Policy in Laravel?


Un policy este o clasa ce defineste un set de permisiuni pentru un user si o resursa data. 

Pentru a crea un policy in laravel putem pur si simplu sa rulam

php artisan make:policy PostPolicy


Sau, pentru a genera un policy legat de un model

php artisan make:policy PostPolicy --model=Post


O data ce am creat o clasa de tipul policy trebuie sa o inregistram in AuthServiceProvider astfel:

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        Post::class => PostPolicy::class,
    ];
 
    /**
     * Register any application authentication / authorization services.
     */
    public function boot(): void
    {
        // ...
    }
}


Acum, dupa ce am generat o clasa de tip policy si am inregistrat-o in AuthServiceProvider putem scrie metodele din aceasta.

De exemplu, pentru actiunea de update putem avea urmatoarea metoda in policy:


class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }
}



Atentie: daca folosim argumentul --model cand general clasa de policy aceasta va avea urmatoarele metode deja generate: viewAny, view, create, update, delete, restore si forceDelete.

Pentru a folosi aceasta clasa de policy, in controller putem scrie urmatorul cod:

class PostController extends Controller
{
    public function update(Request $request, Post $post): RedirectResponse
    {
        if ($request->user()->cannot('update', $post)) {
            abort(403);
        }
 
        // logica de business pentru actiunea data...
    }
}



De asemenea, putem folosi si helper-ul astfel:

class PostController extends Controller
{
    public function update(Request $request, Post $post): RedirectResponse
    {
        $this->authorize('update', $post);
 
        // logica de business pentru actiunea data...
    }
}



Sau si mai simplu, daca folosim ResourceController putem folosi aceasta notatie:

class PostController extends Controller
{
    public function __construct()
    {
        $this->authorizeResource(Post::class, 'post');
    }
}



Metodele corespondende din controller in policy fiind
Metoda din controller -> metoda din policy
index -> viewAny
show -> view
create-> create
store-> create
edit-> update
update-> update
destroy-> delete

Sau direct din middleware astfel:

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

Concluzia

Cam atat am avut pentru acest articol, sper ca v-a fost de folosi si ati invatat ceva de aici.


Imi place ce faci aici
Daca iti place ce fac aici imi poti cumpara o cafea Buy Me a Coffee at ko-fi.com

Stefanescu Mihai
Programator de ~8 ani, am lucrat la proiecte din mai multe industrstrii, de la eCommerce la telecomunicatii la automatizari. In acest timp am folosi diferite tehnologii, de la PHP, MySQL, PostgreSql, RabbitMq, Redis, Memcached si altele.
       

Get in touch
Pentru nelamuriri, dubii, comentarii si chestii de pe suflet ne putem auzi pe Discord, Reddit sau poti deschide o discutie noua pe forum.

Posteaza un comentariu

Comentarii

Inca nu au fost postate comentarii, fii primul care posteaza un comentariu!

Club-ul este dedicat membrilor si ofera access la mai multe zone ale website-ului.

🗝ïļ Login 🌟 Register

🔖 Bookmarks ⊞
âœĻ Pentru a sustine aceasta comunitate am sa te rog sa te autentifici sau sa te inregistrezi!

🌊ïļ Discord ⊞

Folosim cookie-uri pentru a oferi functionalitatile critice ale aplicatiei Invata-Programare. Folosim cookie-uri si pentru a analiza traficul, pentru care e nevoie de consimtamantul dvs. explicit.

⮆ïļ