İçeriğe atla
Tüm makaleler

Postgres RLS ve çalışma alanı kimlik doğrulaması ile çok kiracılı SaaS izolasyonu

Kiracı verilerinin web, mobil ve arka plan işlerinde izole kalması için sunucu tarafı canlı çalışma alanı üyelik korumalarını indekslenmiş Postgres Row-Level Security politikalarıyla birleştirin.

supastack ekibi2 dk okuma

Should I use Postgres Row-Level Security or application-level workspace checks?

It depends on how your application connects to Postgres. If browser or mobile clients query the database directly through PostgREST, Row-Level Security (RLS) is mandatory. If all traffic flows through a server-side TypeScript boundary, explicit membership checks on every query are your primary defense, and RLS serves as defense-in-depth against forgotten WHERE clauses. Combine live session-to-membership resolution with indexed workspace_id policies. supastack enforces server-side workspace guards across web, mobile, and desktop, and provides a free RLS policy generator for Supabase tables.

Uygulama korumaları ve veritabanı politikaları farklı arızaları çözer

Geliştiriciler genellikle uygulama düzeyinde yetkilendirme ile Postgres Row-Level Security'yi (RLS) birbirini dışlayan seçenekler olarak görür. Pratikte farklı hataları yakalarlar: sunucu tarafı korumalar iş mantığı çalışmadan önce rol hiyerarşisini, erişim hakkı kontrollerini ve denetim kayıtlarını uygularken, RLS unutulan bir WHERE workspace_id = ... koşulunun tüm kiracıların satırlarını sızdırmasını engeller.

İster Supabase ister Drizzle ile kendi barındırdığınız Postgres'i kullanın, kiracıya ait her tablo boş olmayan bir workspace_id yabancı anahtarı taşımalıdır. Çalışma alanı sınırları yazısı, bu kapsamın neden her zaman sunucuda türetilmesi gerektiğini açıklar.

  • Uygulama korumaları oturum güncelliğini, üye rollerini (owner, admin, member) ve özellik haklarını doğrular.
  • Veritabanı RLS politikaları, doğrudan istemci sorguları veya ham SQL yardımcıları kullanıldığında sert bir güvenlik tabanı oluşturur.
  • Her iki katman da tek bir doğruluk kaynağına dayanır: workspace_members birleştirme tablosu.

Eski çerezlere güvenmek yerine canlı üyeliği çözümleyin

Bir tarayıcı çerezinde veya istemci başlığında currentWorkspaceId saklamak gezinme için kullanışlıdır, ancak çerez bir yetki değil yalnızca bir tercihtir. Bir yönetici ekip arkadaşını çalışma alanından çıkarırsa, o kullanıcının tarayıcısı eski çalışma alanı çerezini tutmaya devam eder.

Her istekte etkin oturumu workspace_members tablosuyla birleştirin. Üyelik satırı silindiğinde, bir JWT'nin veya oturum çerezinin süresinin dolmasını beklemek yerine isteği derhal reddedin. Giriş formunun ötesinde kimlik doğrulama yazısı, kimliğin bu kontrole nasıl aktığını adım adım izler.

export async function requireWorkspaceViewer(requestedWorkspaceId?: string) {
  const session = await requireAuthenticatedSession();
  const membership = await db.query.workspaceMembers.findFirst({
    where: and(
      eq(workspaceMembers.userId, session.user.id),
      requestedWorkspaceId
        ? eq(workspaceMembers.workspaceId, requestedWorkspaceId)
        : undefined,
    ),
    with: { workspace: true },
  });

  if (!membership) throw new ForbiddenError("Not a member of this workspace");
  return { user: session.user, workspace: membership.workspace, role: membership.role };
}

Hızlı ve indekslenmiş Row-Level Security politikaları yazın

Her satırda doğrudan auth.uid() çağıran saf RLS politikaları, Postgres'i fonksiyonu her satır için yeniden hesaplamaya zorlar. (select auth.uid()) ifadesini skaler bir alt sorguya almak, sorgu planlayıcısının değeri bir initPlan olarak önbelleğe almasını sağlar ve (workspace_id, user_id) üzerindeki bileşik bir indeks üyelik aramalarını milisaniyenin altında tutar.

Elle tekrarlayan SQL yazmadan çok kiracılı tablolar için çalıştırmaya hazır SELECT, INSERT, UPDATE ve DELETE politikalarını ücretsiz Supabase RLS Politika Oluşturucu ile üretebilirsiniz.

CREATE INDEX IF NOT EXISTS idx_workspace_members_lookup
  ON workspace_members (workspace_id, user_id);

ALTER TABLE documents ENABLE ROW LEVEL SECURITY;

CREATE POLICY "workspace_members_manage_documents"
ON documents FOR ALL TO authenticated
USING (
  workspace_id IN (
    SELECT wm.workspace_id FROM workspace_members wm
    WHERE wm.user_id = (SELECT auth.uid())
  )
)
WITH CHECK (
  workspace_id IN (
    SELECT wm.workspace_id FROM workspace_members wm
    WHERE wm.user_id = (SELECT auth.uid())
      AND wm.role IN ('owner', 'admin', 'member')
  )
);

RLS ve çalışma alanı kimlik doğrulaması hakkında sık sorulan sorular

Çok kiracılı Postgres kuran ekipler; servis rolleri, arka plan işleri ve performans etrafında aynı uç durumlarla karşılaşır.

  • Drizzle ORM veya Prisma RLS'yi atlar mı? — Evet, sunucunuz postgres süper kullanıcısı veya Supabase service_role anahtarıyla bağlanıyorsa atlar. Bu nedenle sunucu eylemleri ve API rotaları requireWorkspaceViewer() çağırmalı ve her sorguyu workspaceId ile sınırlandırmalıdır.
  • RLS politikalarında (select auth.uid()) neden parantez içine alınır? — Postgres iyileştiricisine auth.uid() değerini taranan her satır yerine sorgu başına bir kez değerlendirmesini söyler ve büyük tablolarda sıralı tarama yavaşlamalarını önler.
  • Arka plan işleri kiracı verilerine nasıl erişmelidir? — Doğrulanmış workspaceId değerini kimliği doğrulanmış sunucu rotasından iş yüküne aktarın ve çalışan okuma/yazma işlemlerini bu workspaceId ile sınırlandırın.
  • Kiracı izolasyonunun gerçekten korunduğunu nasıl doğrularım? — Kullanıcı A'nın web, mobil ve API rotaları üzerinden Kullanıcı B'nin kayıt kimliğini istediği veya değiştirmeye çalıştığı otomatik negatif testler yazın ve sıfır satır değişikliğiyle 403 / 404 döndüğünü doğrulayın.

Sık sorulan sorular

14 soru

supastack nedir?

supastack, YZ destekli SaaS ürünleri oluşturmak için modüler bir temeldir. Ortak altyapıyı bir araya getirir, böylece ürüne özgü özelliklere odaklanabilirsiniz.

Web ve mobil destekliyor mu?

Evet. supastack, web ve mobil deneyimler için başlangıç noktası olarak Next.js ve Expo uygulamaları içerir.

Hangi kimlik doğrulama dahil?

Better Auth; e-posta/parola, OTP ve sosyal girişi kapsar. Kişisel çalışma alanları hesapla birlikte sağlanır, böylece ürün kayıtları ilk günden itibaren sınırlı kalır.

YZ'yi nasıl destekliyor?

supastack; yapılandırılabilir çok sağlayıcılı YZ, kullanım takibi, bütçeler ve şifreli kendi-anahtarını-getir desteği içerir.

Abonelikler nasıl ele alınıyor?

Kit üzerine kurulu ürünler için Stripe faturalama, abonelikler ve yetkilendirmeler ücretli erişim temelini oluşturur. Sağlayıcı gizli anahtarları yalnızca sunucuda kalır.

Ürüne özgü kodum nerede durur?

Ürüne özgü özellikler ayrı bir kod tabanında kalırken ürün, supastack'in temel modüllerini yapılandırır ve entegre eder.

supastack fiyatlandırması nasıl çalışır?

Kit, ömür boyu güncellemeli tek seferlik bir satın alımdır: 249 $'a Single Stack — Next.js (Web), Expo (iOS ve Android) veya Tauri (macOS ve Windows Masaüstü) depolarından biri —, 398 $'a istediğiniz iki depoyla Dual Stack ya da üç deponun tamamını ve tam monorepo'yu içeren 399 $'lık Full Bundle; ek geliştirici koltuğu başına 75 $. Kit aboneliği yok. Bu sitedeki ödeme, lisans anahtarınızı e-postayla teslim eder ve depo erişimi GitHub davetiyle sağlanır.

Çalışma alanları verilerimi nasıl sınırlar?

Kullanıcıya ait kayıtlar workspaceId ile sınırlanır. Kimlik, yetkilendirmeler, YZ kullanımı, faturalama olayları ve denetim kayıtları kişisel çalışma alanı sınırının içinde kalır.

Arka plan işleri nasıl çalışır?

Trigger.dev açık iş çalışma zamanıdır. JobRunner sözleşmesi yalnızca enqueue, status ve cancel vaat eder — iş akışı semantiği Trigger.dev'e özgü ve açık kalır.

E-posta, tanıtım yazılarından nasıl farklı?

İşlemsel e-posta, tamamlanma bildirimleri gibi ürün iş akışlarını kapsar. Soğuk tanıtım ve kampanyalar, bu kitin e-posta modülünün dışında kalan ürün konularıdır.

Mobil satın almalar nasıl çalışır?

Mobil uygulama RevenueCat ile yerel satın alma ve geri yükleme sunar; erişimi sunucunuz doğrular. Yayınlamadan önce mağaza hesaplarını yapılandırın ve cihaz testlerini tamamlayın. Web faturalandırması ayrı kalır.

YZ sağlayıcı anahtarları nerede durur?

Kendi-anahtarını-getir kimlik bilgileri şifrelidir ve yalnızca sunucuda kalır. Anahtarlar günlüklerden gizlenir; kullanım ve bütçeler çalışma alanı düzeyinde görünür kalır.

Ödeme hangi ödeme yöntemlerini kabul ediyor?

Stripe tarafından barındırılan ödeme sayfası kartları kabul eder; cüzdanlar Stripe hesabında etkinleştirildiğinde Alipay ve WeChat Pay de sunabilir — Çin'deki alıcılar için kullanışlı. Cüzdan yetkilendirmeleri eşzamansız onaylanır; ödeme tamamlanır tamamlanmaz lisans sayfası güncellenir.

Geri ödeme alabilir miyim?

Depoya erişim kazandıktan sonra supastack sonsuza kadar sizin olur, bu nedenle geri ödeme yapılamaz. Ancak içiniz rahat olsun: kendiniz veya müşterileriniz için sınırsız sayıda ürün geliştirip yayınlamak üzere ömür boyu güncellemeler içeren eksiksiz kaynak koduna sahip olursunuz. Yalnızca kodu yeniden satamaz veya depoyu bir başlangıç kiti ya da şablon olarak yeniden dağıtamazsınız. Tek bir istisna vardır: lansman nakit iadesi — supastack ile geliştirilmiş canlı bir ürün yayınlayın, paylaşın ve 60 gün içinde 5.000 organik görüntüleme veya 50 organik beğeniye ulaşarak ödediğiniz tutarın %50'sini geri alın; ayrıntılar için koşullara bakın.

TR