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 |