Laravel'de Multi-Tenant SaaS: Bir Veritabanı, Global Scope ve Kaçan Sızıntılar
Üç ayda bir faturalandırma SaaS'ı hazırlayan bir ekip düşün. Her sorgu `where('company_id', $companyId)` taşır, kod incelemelerinde herkes bunu kontrol eder ve altı ay sorunsuz geçer. Sonra birisi gece yarısı vadesi geçmiş faturaları hatırlatmak için bir iş ekler. Scheduler bunu çalıştırır, oturum açmış kullanıcı yoktur, ve şirket kimliğini sağlayan yardımcı null döner. Sorgu filtresini sessizce kaybeder ve iş tüm şirketlerin faturalarını okur.
Bu hikaye olağandışı değildir. Tenant izolasyonu her geliştirici tarafından bir satırın hatırlanmasına ve request bağlamının iş ve komutlara ulaşmasına bağlı olduğunda tam olarak budur.
Laravel'de tek bir veritabanında şirketleri izole etmek, üç temel konuyu gerektirir: hangi tenant modelini seçeceğin, mevcut şirketi nasıl çözeceğin ve bunu unutulması imkânsız hale nasıl getireceğin.
Global scope kullanmak ilk adımdır, her model otomatik olarak company_id filtresini uygular. Ama bu yeterli değildir. Scheduler, queue job'ları ve artisan komutları request context'inde çalışmaz. Çözüm, middleware'den bağımsız bir tenant resolver oluşturmaktır: bir service provider aracılığıyla geçerli tenant'ı belirle, onu container'a kaydet ve her sorgudan önce kontrol et.
Test etmek kritiktir. Tenant leak'lerini yakalamak için her test'te farklı şirketlerle veri oluştur, sonra sorguların sadece o tenant'ın verilerini döndürdüğünü doğrula. Bir scheduler job'ı test ederken, context olmadan çalıştığını simüle et, null company_id ile ne olacağını gör.
Eğer izolasyon kodun her yerinde elle uygulanıyorsa, sızıntı kaçınılmazdır. Mekanizmi framework'e em dirlersen, unutmak imkânsız hale gelir.
0 yorum