Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Yazı Tipi BoyutlandırıcıAa
  • Anasayfa
  • Teknoloji
    • Siber Güvenlik
    • Yapay Zeka
    • Donanım
    • Bilim
  • Yazılım
  • Savunma & İstihbarat
  • Oyun
  • Yaşam
    • Finans
    • Sinema
    • Dünyadan Haberler
  • İş Birliği
Okuma: Laravel ile Çoklu Kiracı SaaS: Harici Paket Kullanımı Olmadan Otomatik Veri İzolasyonu İçin Global Scope’lar
Paylaş
Yazı Tipi BoyutlandırıcıAa
Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Ara
Bizi Takip Et
  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti
© 2026 Teknomers. All Rights Reserved.

Anasayfa » Laravel ile Çoklu Kiracı SaaS: Harici Paket Kullanımı Olmadan Otomatik Veri İzolasyonu İçin Global Scope’lar

Yazılım

Laravel ile Çoklu Kiracı SaaS: Harici Paket Kullanımı Olmadan Otomatik Veri İzolasyonu İçin Global Scope’lar

teknomers
Son güncelleme: 12 Mayıs 2026 19:12
teknomers
Paylaş
Paylaş

Bir B2B SaaS platformu geliştirirken, kritik bir mimari karar vermek durumunda kaldım: her kiracıya ayrı bir veritabanı mı yoksa mantıksal izolasyon ile paylaşılan bir veritabanı mı kullanılmalı?

Ben paylaşılan veritabanını seçtim. İşte nedenleri ve nasıl sağlam veri izolasyonu sağladığımı anlatan süreç.


Neden Paylaşılan Veritabanı?

Bir B2B SaaS için, veritabanı evrimi oldukça kritik:

Artılar:

  • Atomik migration’lar (bir sütun eklemek, 500 kez değil)
  • Basitleştirilmiş yedekleme/geri yükleme
  • Daha düşük alt yapı maliyetleri

Eksiler:

  • Fiziksel değil, mantıksal izolasyon
  • Gürültücü komşu riski

Eğer 500 kiracıya ulaşırsam, her özellik için 500 ayrı migration yönetmek tam zamanlı bir iş olurdu. Paylaşılan veritabanı kazanıyor.


Mimari

USER REQUEST
     │
     ▼
MIDDLEWARE (EnsureTenantAccess)
     │ 1. Verify authentication
     │ 2. Extract tenant ID
     │ 3. Store in TenantContext (singleton)
     ▼
ELOQUENT MODELS (with BelongsToTenant trait)
     │ 4. Apply GlobalScope automatically
     ▼
DATABASE QUERY
     SELECT * FROM table WHERE tenant_id = [X]


TenantContext: Doğrunun Kaynağı

class TenantContext
{
    private ?string $tenantId = null;

    public function set(string $id): void
    {
        $this->tenantId = $id;
    }

    public function id(): string
    {
        return $this->tenantId;
    }

    public function isSet(): bool
    {
        return $this->tenantId !== null;
    }
}

Singleton. Her istek için bir örnek. Hiçbir belirsizlik olmadan.


BelongsToTenant Trait

Burası sihrin gerçekleştiği yer:

trait BelongsToTenant
{
    public static function bootBelongsToTenant(): void
    {
        // OKUMA: Tüm sorguları otomatik olarak filtrele
        static::addGlobalScope('tenant', function (Builder $query) {
            $context = app(TenantContext::class);
            if ($context->isSet()) {
                $query->where('tenant_id', $context->id());
            }
        });

        // YAZMA: Oluşturma işlemi sırasında tenant_id'yi otomatik olarak atayın
        static::creating(function (Model $model) {
            $context = app(TenantContext::class);
            if ($context->isSet() && !$model->tenant_id) {
                $model->tenant_id = $context->id();
            }
        });
    }
}

Her kiracıya özel model (Müşteriler, Araçlar, Taşıma) bu trait’i kullanır. Manuel tenant_id ataması yok. Unutkanlık hataları yok.


Kiracılar Arası İzolasyonu Test Etme

public function test_cross_tenant_isolation(): void
{
    $tenantA = Tenant::factory()->create();
    $tenantB = Tenant::factory()->create();

    Product::factory()->for($tenantA)->create(['name' => 'Item A']);
    Product::factory()->for($tenantB)->create(['name' => 'Item B']);

    $response = $this->actingAs($this->userInTenant($tenantA))
        ->getJson('/api/v1/products');

    $response->assertOk();
    $response->assertJsonCount(1, 'data');
    $response->assertJsonPath('data.0.name', );
}

Bu test olmadan, GlobalScope’un çalıştığını sadece umut ediyorum. Umut, bir strateji değil.


Süper Yönetici Taklit Etme

Destek, müşterilerin gördüklerini görebilmelidir. Çözüm:

$tenantId = $user->isSuperAdmin()
    ? session()
    : $user->tenant_id;

Süper yönetici, sabit bir tenant_id’ye sahip değildir. Panel üzerinden bir kiracıyı taklit etmek için seçer. Oturum, ID’yi saklar. Middleware, TenantContext’i doldurur. Tam olarak müşteriyle aynı görünümler.


Salt Okuma Modu

if ($tenant->is_read_only && $request->isMethodSafe() === false) {
    abort(403, );
}

Kullanım senaryoları:

  • Ödeme durdurmayı
  • Bakım pencereleri
  • Soruşturma kilitlerini

Tüm bunlar middleware içinde merkezi hale getirilir. Controller kirliliği yok.


Öğrenilen Anti-Durumlar

  1. Manuel tenant_id ataması: Unutacaksınız. Trait kullanın.
  2. Tenant_id olmadan benzersiz indeksler: Her zaman bileşik (tenant_id + unique_field) kullanın.
  3. Kiraçılar için artan ID’ler: UUID’leri kullanın. ID tahmin saldırılarını önler.


Bir Paket Kullanır Mıyım?

Spatie’nin spatie/laravel-multitenancy paketi sağlamdır.

Ancak kendi çözümümü geliştirmek bana şu avantajları sağladı:

  • Sınırlı durumlar üzerinde tam kontrol
  • Süper yönetici taklit etme (paketlerle basit değil)
  • İzolasyon sınırları hakkında derin anlayış

Öğreniyorsanız veya özel akışlara ihtiyacınız varsa, kendiniz inşa edin. Hız ve standart desenlere ihtiyacınız varsa, bir paket kullanın.


Sonuç

Laravel ile çok kiracılılık, otomasyonunuza güvenmek, insan hafızanıza güvenmemek ile ilgilidir.

Global Scopes + TenantContext + kapsamlı testler = gece rahat uyuyun.

Kaynak: Orijinal Makale

Contents
  • Neden Paylaşılan Veritabanı?
    • Mimari
    • TenantContext: Doğrunun Kaynağı
    • BelongsToTenant Trait
    • Kiracılar Arası İzolasyonu Test Etme
    • Süper Yönetici Taklit Etme
    • Salt Okuma Modu
    • Öğrenilen Anti-Durumlar
    • Bir Paket Kullanır Mıyım?
    • Sonuç
Filament v5’te Kaynak Oluşturma | Laravel Kişisel Finans Panosu
Üretim Uygulamalarınızı Kodu Durdurun: Geliştirici Odaklı Yapay Zeka İçin Bir Gerekçe
S3 Uyumluluğunda Yedekleme Depolama: AWS, DigitalOcean Spaces, Backblaze B2 ve Diğerleri
İlk Kez Sunucu Yöneticisi Olanların Yaptığı 7 Hata (ve Deploynix’in Bunları Nasıl Önlediği)
Livewire ve Inertia Tartışmasını Neden Düşünmeyi Bıraktım (ve Birini Nasıl Seçersiniz)
Bu Makaleyi Paylaş
Facebook Bağlantıyı Kopyala Yazdır
Paylaş
Önceki Makale Exaforce’tan Siber Saldırılara Anında Yanıt Veren AI Geliştirme Adımı
Sonraki Makale Sam Altman, Elon Musk’a Karşı Dava Sürecinde Tanıklık Ediyor

Sanal Medya

FacebookBeğen
452Takip Et
PinterestSabitle
237Takip Et

Son Eklenenler

Yeni Steam Çerçeve Kurulumu Videosu Yakın Çıkış Tarihini İşaret Ediyor
Oyun
Nintendo Gösteriminde Hazırlıksız Olmamak için Dikkatli Olmalı
Oyun
Apple’ın Uygulama Mağazası Kişiselleştirilmiş Öneriler Sunmaya Başladı
Genel
Microsoft’un AI Lideri, Anthropic’ın Claude’un Bilinçli Davrandığını İddia Etmesini Eleştirdi
Liste
SAP, NetWeaver ve Commerce Cloud’da Acil Kritik Açıkları Giderdi
Siber Güvenlik
Riot’tan Yeni Karakter: League of Legends’ın Locke’u Tanıtıldı
Oyun
//

Siber güvenlik, yapay zeka ve savunma sanayiinden; finans ve sinema dünyasına uzanan geniş bir yelpaze. Teknomers; teknoloji, strateji ve yazılım dünyasını sade bir dille sizlerle buluşturuyor.

Kurumsal

  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti

Kategoriler

  • Teknoloji
  • Oyun
  • Sinema
  • Siber Güvenlik
  • Bilim
  • Finans
  • Dünyadan Güncel Haberler

Populer

  • TV'de Ücretsiz İzlenebilen Şifresiz Erotik Kanallar (2025 Güncel Frekans Listesi)

  • The Last of Us PC Kontrolleri: Hızlı Silah Değiştirme ve Tüm Tuşlar (2025)

  • Hogwarts Legacy'de Odaklanma İksiri Nasıl Yapılır?

Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Bizi Takip Et
© 2026 Teknomers. All Rights Reserved.
Welcome Back!

Sign in to your account

Kullanıcı Adı veya E-posta Adresi
Şifre

Şifrenizi mi unuttunuz?