Laravel İle Çoklu Kullanıcı Rolüne Dayalı Yetki Sistemi Nasıl Yapılır?

Laravel İle Çoklu Kullanıcı Rolüne Dayalı Yetki Sistemi Nasıl Yapılır?
Laravel İle Çoklu Kullanıcı Rolüne Dayalı Yetki Sistemi Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Bu uygulamayı gerçekleştirmek için sisteminizde PHP 8.3 veya üzeri bir sürümün ve Laravel 11/12 framework yapısının kurulu olması gerekmektedir. Veritabanı yönetimi için MySQL veya PostgreSQL kullanabilirsiniz. Geliştirme ortamınızda Composer'ın güncel olduğundan emin olun.

  • Laravel 11+ veya 12 framework kurulumu.
  • Veritabanı bağlantısı yapılandırılmış bir proje.
  • Temel düzeyde Eloquent ORM ve Migration bilgisi.

Veritabanı Şemasını Hazırlama

Kullanıcıların rollerini tutmak için en yaygın ve esnek yöntem, kullanıcı tablosuna bir 'role' sütunu eklemek veya ayrı bir 'roles' tablosu ile ilişki kurmaktır. Küçük ve orta ölçekli projeler için hızlı bir başlangıç olarak kullanıcı tablosuna 'role' sütunu ekleyeceğiz.

// Migration dosyanızda (database/migrations/xxxx_add_role_to_users_table.php)
public function up(): void
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('role')->default('user'); // admin, editor, user
    });
}

Bu kod, mevcut kullanıcılar tablosuna varsayılan değeri 'user' olan bir rol sütunu ekler. Veritabanı güncellemelerini php artisan migrate komutu ile uygulayın.

Laravel Middleware ile Erişim Kontrolü

Middleware, gelen HTTP isteklerini kontrol eden bir filtredir. Belirli bir rotaya sadece 'admin' rolüne sahip kullanıcıların girmesini sağlamak için özel bir middleware oluşturmalıyız.

// Terminalde çalıştırılacak komut
php artisan make:middleware EnsureUserHasRole

Oluşturulan middleware içerisinde, kullanıcının rolünü kontrol eden mantığı yazacağız. Eğer kullanıcı yetkili değilse, onu ana sayfaya yönlendireceğiz.

// app/Http/Middleware/EnsureUserHasRole.php
public function handle(Request $request, Closure $next, string $role): Response
{
    if ($request->user() && $request->user()->role !== $role) {
        return redirect('/dashboard')->with('error', 'Bu sayfaya erişim yetkiniz yok.');
    }

    return $next($request);
}

Bu yapı, rotalara dinamik olarak rol parametresi göndermenize olanak tanır. Örneğin role:admin şeklinde bir kontrol sağlayabilirsiniz.

Rota Koruması ve Yetkilendirme

Oluşturduğumuz middleware'i Laravel rotalarında kullanmak için bootstrap/app.php dosyasında tanımlamamız gerekir. Bu sayede rotalarımızı güvenli hale getirebiliriz.

// bootstrap/app.php içerisinde
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'role' => \App\Http\Middleware\EnsureUserHasRole::class,
    ]);
})

Artık rotalarımızı şu şekilde koruyabiliriz:

// routes/web.php
Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::get('/admin/dashboard', [AdminController::class, 'index']);
});

Bu kod bloğu, hem giriş yapılmış olmasını (auth) hem de kullanıcının rolünün 'admin' olmasını zorunlu kılar. Bu, yetkisiz erişimleri engellemek için en etkili yoldur.

Blade Şablonlarında Yetki Kontrolü

Sadece rotaları korumak yeterli değildir; kullanıcı arayüzünde de yetkili olmayan butonları gizlemelisiniz. Blade direktiflerini kullanarak bunu kolayca yapabilirsiniz.

// resources/views/dashboard.blade.php
@if(auth()->user()->role === 'admin')
    Sistem Ayarları
@endif

Bu basit kontrol, admin olmayan kullanıcıların arayüzde görmemesi gereken öğeleri gizler. Ancak unutmayın, bu sadece görsel bir gizlemedir; asıl güvenlik her zaman sunucu tarafındaki middleware ile sağlanmalıdır.

Yetkilendirme Yöntemlerinin Karşılaştırması

Yöntem Avantaj Dezavantaj
Middleware Merkezi ve güvenli Her rota için tanımlanmalı
Gates/Policies Esnek ve nesne odaklı Öğrenme eğrisi biraz daha yüksek
Package (Spatie) Çok hızlı kurulum Dış bağımlılık ekler
Kritik Güvenlik Uyarısı: Kullanıcı rollerini asla istemci tarafında (JavaScript) doğrulamaya güvenerek yönetmeyin. İstemci tarafındaki tüm kontroller sadece kullanıcı deneyimi içindir. Asıl yetkilendirme her zaman sunucu tarafında (Controller veya Middleware) yapılmalıdır.

Sıkça Sorulan Sorular

Bir kullanıcıya birden fazla rol atayabilir miyim?

Bu rehberde basitlik adına tek rol yapısı kullandık. Birden fazla rol için 'roles' ve 'permissions' tabloları oluşturarak 'many-to-many' (çoka-çok) ilişkisi kurmanız ve Spatie Permission gibi paketleri incelemeniz önerilir.

Middleware neden çalışmıyor?

Middleware'in bootstrap/app.php dosyasında doğru alias ile tanımlandığından ve rotada doğru isimle çağrıldığından emin olun. Ayrıca auth middleware'inin önce çalıştığından emin olun.

Yetkisiz erişim olduğunda ne yapmalıyım?

Yetkisiz erişim durumunda kullanıcıyı 403 Forbidden sayfasına yönlendirmek en doğru HTTP standartıdır. abort(403) fonksiyonunu kullanabilirsiniz.

Veritabanı güncellemeleri üretim ortamında riskli mi?

Evet, üretim ortamında migration çalıştırmadan önce mutlaka veritabanı yedeği alın ve değişiklikleri staging ortamında test edin.

Rol isimlerini nasıl yönetmeliyim?

Rol isimlerini string olarak yazmak yerine, User modelinde sabitler (constants) tanımlayarak hata yapma riskini azaltabilirsiniz.

İleri Düzey Yetkilendirme: Laravel Policies ile Nesne Tabanlı Kontrol

Middleware kullanımı basit erişim kısıtlamaları için harika olsa da, belirli bir kaynak (resource) üzerinde işlem yapma yetkisini kontrol etmek istediğinizde Laravel Policies yapısı çok daha temiz ve sürdürülebilir bir çözüm sunar. Örneğin, bir kullanıcının sadece kendi oluşturduğu makaleyi düzenleyebilmesi gibi senaryolar için Policy sınıfları vazgeçilmezdir.

Öncelikle, terminal üzerinden bir Policy sınıfı oluşturalım:

php artisan make:policy PostPolicy --model=Post

Oluşturulan app/Policies/PostPolicy.php dosyasında, kullanıcının rolünü ve kaynağın sahipliğini kontrol eden mantığı şu şekilde kurabilirsiniz:

public function update(User $user, Post $post)
{
    // Admin her şeyi düzenleyebilir, editör ise sadece kendi yazdığını
    if ($user->hasRole('admin')) {
        return true;
    }

    return $user->id === $post->user_id;
}

Bu yetkiyi kontrol etmek için Controller içerisinde veya Blade şablonlarında @can direktifini kullanabilirsiniz:

@can('update', $post)
    Düzenle
@endcan

Performans Optimizasyonu: Yetki Sorgularını Önbelleğe Alma

Rol ve izin tabanlı sistemlerde, her sayfa yüklenişinde veritabanına gidip kullanıcının rollerini sorgulamak, özellikle yüksek trafikli uygulamalarda performans darboğazına neden olabilir. Laravel'in Cache mekanizmasını kullanarak bu sorguları optimize etmek oldukça önemlidir.

User modelinizde rollerin çekildiği metodu, veritabanı yükünü azaltmak için şu şekilde güncelleyebilirsiniz:

public function getRolesAttribute()
{
    return Cache::remember('user_roles_' . $this->id, 3600, function () {
        return $this->roles()->get();
    });
}

Önemli İpucu: Kullanıcının rolü veya izni güncellendiğinde, ilgili önbelleği temizlemeyi unutmamalısınız. Aksi takdirde kullanıcı yetkileri değişse bile sistem eski veriyi göstermeye devam eder:

public function updateRole($newRole)
{
    $this->roles()->sync($newRole);
    Cache::forget('user_roles_' . $this->id);
}

Bu yaklaşım, veritabanı üzerindeki okuma yükünü ciddi oranda düşürürken, uygulamanızın yanıt süresini (response time) milisaniyeler seviyesinde iyileştirecektir. Büyük ölçekli projelerde bu tür bir önbellekleme stratejisi, sistemin ölçeklenebilirliğini doğrudan etkileyen kritik bir unsurdur.

Sonuç

Laravel ile çoklu kullanıcı rolüne dayalı yetki sistemi kurmak, uygulamanızın güvenliğini profesyonel bir seviyeye taşır. Bu rehberde, middleware yapılandırmasından Blade şablonlarına kadar temel yetkilendirme mantığını adım adım uyguladık. Bir sonraki adım olarak, Laravel'in Gate ve Policy yapılarını inceleyerek, daha karmaşık ve nesne tabanlı yetkilendirme kuralları oluşturmayı öğrenebilirsiniz.

Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamına almadan önce kendi güvenlik testlerinizi yapmalı ve SQL injection gibi açıklara karşı Laravel'in sunduğu Eloquent ORM'in koruyucu özelliklerini her zaman kullanmalısınız.
Bu yazıya tepkinizi paylaşın:
Selin Yılmaz

Zaman yönetimi ve üretkenlik ipuçları üzerine uzmanlaşmış bir içerik yazarıyım. Günlük yaşamı kolaylaştıran etkili yöntemleri okuyucularla paylaşarak hayat kalitesini artırmayı hedefliyorum.

Yorumlar (0)

Yorum Yaz