Muzibu Admin Panel 403 Hatası

Spatie Permission Cache Bozulması ve Çözümü

Tarih
9 Ocak 2026
🚨

Sorun Özeti

Muzibu (Tenant 1001) admin paneline ve Horizon'a giriş yapılamıyordu. Database'de ROOT yetkisi olmasına rağmen sürekli 403 Forbidden hatası alınıyordu.

403 Forbidden Admin Panel Horizon Spatie Permission

📝 Basit Anlatım (Herkes İçin)

Ne Oldu?

Site yöneticileri (nurullah@nurullah.net ve info@turkbilisim.com.tr) admin paneline girmeye çalıştıklarında "Erişim Reddedildi" hatası alıyorlardı. Oysa database'de (veritabanı) tam yetkileri vardı.

Neden Oldu?

Laravel'in yetki sistemi (Spatie Permission), kullanıcı yetkilerini hızlı erişim için geçici hafızada (cache) tutuyor. Bu geçici hafıza bozulmuştu ve kullanıcıların yetkilerini göremiyordu. Sanki "Yöneticinin yetkilerini gösteren bir not kağıdı eskimiş ve okunamaz hale gelmişti."

Nasıl Çözüldü?

  1. Bozuk not kağıdı atıldı (cache temizlendi)
  2. Veritabanından yetkileri tekrar okutup yeni bir not yazıldı (syncRoles)
  3. Kullanıcıların eski oturumu kapatıldı (session silindi)
  4. Yeni oturum açtıklarında artık yeni, doğru yetkiler yüklendi

✅ Sonuç: Logout yapıp yeniden login olduktan sonra her şey düzeldi. Admin panel ve Horizon'a giriş yapılabildi.

🔧 Teknik Detaylar (Geliştiriciler İçin)

Database Doğru'ydu

-- model_has_roles tablosu
role_id: 1 (root)
model_id: 1, 2
model_type: 'App\\Models\\User'
-- role_has_permissions tablosu
ROOT role → 108 permission (hepsi)

Dosya: tenant_muzibu_1528d0 database (tenant context)

Spatie Permission Cache Bozuktu

Tinker Test Sonucu:
$user = User::find(1);
$user->roles->count(); // 0 (YANLIŞ!)
$user->hasRole('root'); // false (YANLIŞ!)
$user->isRoot(); // false (YANLIŞ!)

Database'de rol atanmış olmasına rağmen Laravel runtime'da role relationship boş dönüyordu. Sebep: Spatie Permission cache'i Redis'te bozuk/eski format'ta saklanmıştı.

Session'da Eski User Object

Login olunduğunda user object session'a kaydedilmişti. Bu object'te roles = [] (boş array) vardı. Her sayfa yüklendiğinde bu eski session'dan okunuyordu, dolayısıyla cache temizleme bile yeterli olmadı.

Session flow:
1. Login → User cached (roles = [])
2. Cache clear → Session'da user hala eski
3. Her request → Session'dan eski user yüklenir
4. Sonuç: 403 Forbidden

Uygulanan Çözüm

1

Tinker ile Role Sync

// Tenant context'te
$user1 = User::find(1);
$user1->syncRoles(['root']);
$user2 = User::find(2);
$user2->syncRoles(['root']);

Etki: Spatie Permission cache'ini temizler ve role relationship'i fresh yükler

2

Redis FLUSHDB

redis-cli -n 0 FLUSHDB

Etki: Tüm Spatie cache + Laravel session + diğer cache'ler tamamen silindi

3

Cache Rebuild

php artisan cache:clear
php artisan config:cache
php artisan view:clear
curl https://muzibu.com/opcache-reset.php

Etki: Config cache rebuild + OPcache (PHP bytecode) reset

4

Logout + Login (Kullanıcı)

Kullanıcı logout yapıp yeniden login oldu. Bu sayede:

  • Eski session silindi
  • Yeni session oluştu
  • Fresh user object + fresh roles yüklendi

💡 Neden Bu Çözüm İşe Yaradı?

❌ Önce (Bozuk)

Spatie cache bozuk
$user->roles = [] (boş)
Session'da eski user object
hasRole('root') = false
Middleware 403 döndü

✅ Sonra (Düzeltildi)

syncRoles() → cache refresh
$user->roles = [root] ✓
Redis flush → session silindi
Login → fresh user + roles
Middleware erişim verdi

核心 (Core): syncRoles() fonksiyonu sadece database'e yazmadı, aynı zamanda Spatie Permission'ın internal cache'ini de temizledi. Ardından Redis flush ve logout/login ile session'daki eski user object'i yenilendi. Bu üçlü kombinasyon sorunu tamamen çözdü.

🛡️ Gelecek İçin Önlemler

1.

Role değişikliklerinde cache temizle: Role atama/çıkarma işlemlerinden sonra php artisan permission:cache-reset çalıştır.

2.

Session süresi optimize et: Spatie Permission cache TTL'ini (24 saat) düşür veya session lifetime'ı gözden geçir.

3.

Admin role değişikliği izni: Kritik roller (root, admin) değiştirildiğinde kullanıcıyı otomatik logout et.

4.

Monitoring: AdminAccessMiddleware'de role check fail olduğunda log at (debug için).

📁 İlgili Dosyalar

Middleware
app/Http/Middleware/AdminAccessMiddleware.php
Horizon Gate
app/Providers/HorizonServiceProvider.php
User Model
app/Models/User.php
Permission Config
config/permission.php
Horizon Config
config/horizon.php
Trait
Modules/UserManagement/app/Traits/HasModulePermissions.php