Giriş
Dahili kimlik doğrulama (authentication) servisine ek olarak Laravel, kaynaklara erişim ve yetkilendirme mantığı için kolay bir yol sağlar. Yetkilendirmelerinizin organizasyonunda size yardımcı olacak ve herbirini bu dökümanda açıklayacağımız çeşitli metodlar ve yardımcılar vardır.
Not: Yetkilendirme, Laravel 5.1.11 versiyonunda eklenmiştir.
Yapabilirlik Tanımlama
Bir kullanıcının  verilen işlevi icra edip edemeyeceğini belirlemenin en kolay yolu Illuminate\Auth\Access\Gate sınıfıını kullararak bir “yapabilirlik (ability)” tanımlamaktır. Laravel ile sunulan AuthServiceProvider servis sağlayıcı, uygulamanız için tüm yapabilirlikleri tanımlamak için uygun bir yerdir. Örneğin, mevcut User ve Post modelini alan update-post yapabilirliğini tanımlayalım. Yapabilirliğimizde, kullanıcının id‘sinin post modelinin user_id‘si ile eşleşip eşleşmediğini belirleyeceğiz.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php namespace App\Providers; use Illuminate\Contracts\Auth\Access\Gate as GateContract; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider {     /**      * Yetkilendirme ve kimlik doğrulama servislerini kaydedilmesi      *      * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate      * @return void      */     public function boot(GateContract $gate)     {         parent::registerPolicies($gate);         $gate->define('update-post', function ($user, $post) {             return $user->id === $post->user_id;         });     } } | 
Not olarak; $user değişkeninin NULL olup olmadığını kontrol etmedik. Gate, giriş yapmış bir kullanıcı olmadığında veya forUser metodu kullanılarak bir kullanıcı belirtilmediğinde tüm yapabililirlikler için otomatik olarak false döner.
Sınıf Bazlı Yapabilirlikler
Ek olarak isimsiz fonksiyonları yetkilendirme geri çağırması (callbacks) şeklinde eklemek yerine sınıf adı ve metodunu içeren bir yazıyla da kaydedebilsirsiniz. İhtiyaç duyulduğunda, sınıf servis taşıyıcısı yoluyla çözümlenecektir.
| 1 | $gate->define('update-post', 'Class@method'); | 
Tüm Kontroller Engellemek
Bazen, özel bir kullanıcı için tüm yapabilirlikleri aktifleştirmek isteyebilirsiniz. Bu durumda, before metodunu kullanın ve bunun için diğer yetkilendirme kontrollerinden önce çalışacak bir geri çağırma tanımlayın.
| 1 2 3 4 5 | $gate->before(function ($user, $ability) {     if ($user->isSuperAdmin()) {         return true;     } }); | 
Yapabilirliklerin Doğrulanması
Gate Facade Kullanarak
Gate Facade Kullanarak
Tanımmış bir yapabilirliği çeşitli yollarla doğrulayabiliriz. İlk olarak Gate facade üzerindeki check, allows veya denies metodlarını kullanabiliriz. Tüm bu metodlar yapılabilirliğin isimini ve yapabilirliğin geri çağrımına geçirilecek argümanları alır. Bu metodlara geçerli kullanıcıyı geçirmenize gerek yoktur.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php namespace App\Http\Controllers; use Gate; use App\User; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller {     /**      * Verilen $post güncellemesi.      *      * @param  int  $id      * @return Response      */     public function update($id)     {         $post = Post::findOrFail($id);         if (Gate::denies('update-post', $post)) {             abort(403);         }         // Post güncelle...     } } | 
allows metodu denies metodunun tersidir ve işlem yetkilendirilmişse true döndürülür. check metodu allows metodunun başka bir adıdır ve aynı işlevi yapar.
Yapabilirliğin Özel Kullanıcılar İçin Kontrol Edilmesi
Gate facade mevcut kullanıcının haricinde başka bir kullanıcının yapabilirliğini kontrol için kullanmak isterseniz, forUser metodunu kullanabilirsiniz.
| 1 2 3 | if (Gate::forUser($user)->allows('update-post', $post)) {     // } | 
Çoklu Argüman Geçirme
Yapabilirlik geri çağrımları çoklu argüman alabilir.
| 1 2 3 | Gate::define('delete-comment', function ($user, $post, $comment) {     // }); | 
Yapabilirlik için çoklu argüman geçirmek gerekli ise, Gate metoduna argümanları dizi olarak geçirebilirsiniz.
| 1 2 3 | if (Gate::allows('delete-comment', [$post, $comment])) {     // } | 
“User” Modeli Yoluyla
Alternatif olarak, User model örneği yoluyla yapabilirliği kontrol edebilirsiniz. Varsayılan olarak, Laravel’in App\User modeli can ve cannot metodlarını sağlayan Authorizable  özelliğini (trait) kullanır. Bu metodlar Gate facade ile kullanıllan allows ve denies metodlarına benzer şekilde kullanılabilir. Yani, bir önceki kullandığımız örneğimiz, şu şekilde değiştirilebilir.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php namespace App\Http\Controllers; use App\Post; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class PostController extends Controller {     /**      * Verilen $post güncellemesi.      *      * @param  \Illuminate\Http\Request  $request      * @param  int  $id      * @return Response      */     public function update(Request $request, $id)     {         $post = Post::findOrFail($id);         if ($request->user()->cannot('update-post', $post)) {             abort(403);         }         // Post güncelle...     } } | 
can metodu, cannot metodunun tersi olarak kullanılabilir.
Blade Template İçinde Kullanımı
Kolaylık için Laravel, giriş yapmış bir kullanıcının verilen yapılabilirliği kolayca kontorl edebilmek için @code Blade yönergesi sağlar.
| 1 2 3 4 5 | <a href="/post/{{ $post->id }}">View Post</a> @can('update-post', $post)     <a href="/post/{{ $post->id }}/edit">Edit Post</a> @endcan | 
@can yönergesini @else yönergesini beraber de kullanabilirsiniz.
| 1 2 3 4 5 | @can('update-post', $post)     <!-- Mevcut kullanıcı bu Post'u güncelleyebilir --> @else     <!-- Mevcut kullanıcı bu Post'u güncelleyemez --> @endcan | 
Form İsteklerinde Kullanım
Yapabilirliklerinizi form isteğinin authorize metodunu kullanarak da yapabilirsiniz. Örneğin:
| 1 2 3 4 5 6 7 8 9 10 11 | /**  * Kullanıcının bu isteği yapmaya yetkisi olup olmadığını belirlemek  *  * @return bool  */ public function authorize() {     $postId = $this->route('post');     return Gate::allows('update', Post::findOrFail($postId)); } | 
Politikalar
Politika Yaratılması
Büyük uygulamalarda, tüm yetkilendirme mantığını AuthServiceProvider içinde yapmak kullanışsız olabilir. Laravel yetkilendirme mantığınızı “Politika (Policy)” sınıflarına ayırmanıza izin verir.
Önce, Post modelimize yetkilendirmeyi yönetmek için bir politika oluşturalım. make:policy artisan komutunu kullanarak yeni bir politika oluşturabilirsiniz. Oluşturulan politika app/Policies klasörüne konacaktır.
| 1 | php artisan make:policy PostPolicy | 
Politikaların Kaydedilmesi
Varolan politikayı, Gate sınıfında kaydetmemiz gerekir. AuthServiceProvider, policies özelliği içerir.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php namespace App\Providers; use App\Post; use App\Policies\PostPolicy; use Illuminate\Contracts\Auth\Access\Gate as GateContract; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider {     /**      * The policy mappings for the application.      *      * @var array      */     protected $policies = [         Post::class => PostPolicy::class,     ]; } | 
Politikalar Yazılması
Potilika oluşturulduktan ve kaydettikten sonra, yetkilendirilecek her yapabilirlik için bir metod ekleyebiliriz. Örneğin, verilen kullanıcının Post guncelleme yapıpıp yapamayacağına karar veren PostPolicy sınıfımızda “update” metodu tanımlayalım.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php namespace App\Policies; use App\User; use App\Post; class PostPolicy {     /**      * Kullanıcı tarafından post'un güncelleyebileceğinin belirlenmesi      *      * @param  \App\User  $user      * @param  \App\Post  $post      * @return bool      */     public function update(User $user, Post $post)     {         return $user->id === $post->user_id;     } } | 
Politikaya ihtiyaç durduğunuz diğer yetelilikler için metodlar eklemeye devam edebilirsiniz. Örneğin, çeşitli Post işlemlerinin yetkilendirilmesi için show, destroy, addCommnent metodlar tanımlayabilirsiniz.
Tüm Kontroller Engellemek
Bazen, özel bir kullanıcı için tüm yapabilirlikleri aktifleştirmek isteyebilirsiniz. Bu durumda, before metodunu kullanın ve bunun için diğer yetkilendirme kontrollerinden önce çalışacak bir geri çağırma tanımlayın.
| 1 2 3 4 5 | $gate->before(function ($user, $ability) {     if ($user->isSuperAdmin()) {         return true;     } }); | 
Politikaların Doğrulanması
Gate Facade Kullanarak
Gate Facade Kullanarak
Tanımmış bir yapabilirliği çeşitli yollarla doğrulayabiliriz. İlk olarak Gate facade üzerindeki check, allows veya denies metodlarını kullanabiliriz. Tüm bu metodlar yapılabilirliğin isimini ve yapabilirliğin geri çağrımına geçirilecek argümanları alır. Bu metodlara geçerli kullanıcıyı geçirmenize gerek yoktur.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php namespace App\Http\Controllers; use Gate; use App\User; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller {     /**      * Verilen $post güncellemesi.      *      * @param  int  $id      * @return Response      */     public function update($id)     {         $post = Post::findOrFail($id);         if (Gate::denies('update-post', $post)) {             abort(403);         }         // Post güncelle...     } } | 
Blade Template İçinde Kullanımı
Kolaylık için Laravel, giriş yapmış bir kullanıcının verilen yapılabilirliği kolayca kontorl edebilmek için @code Blade yönergesi sağlar.
| 1 2 3 4 5 | <a href="/post/{{ $post->id }}">View Post</a> @can('update-post', $post)     <a href="/post/{{ $post->id }}/edit">Edit Post</a> @endcan | 
@can yönergesini @else yönergesini beraber de kullanabilirsiniz.
| 1 2 3 4 5 | @can('update-post', $post)     <!-- Mevcut kullanıcı bu Post'u güncelleyebilir --> @else     <!-- Mevcut kullanıcı bu Post'u güncelleyemez --> @endcan |