Sicherheitsregeln (RLS)
Übersicht
Abschnitt betitelt „Übersicht“Sicherheitsregeln ermöglichen es Ihnen, Row Level Security (RLS)-Richtlinien für Ihre PostgreSQL-Tabellen direkt in Ihren Sammlungsdefinitionen zu definieren. Wenn das Drizzle-Schema generiert wird, erstellt Rebase die entsprechenden CREATE POLICY-Anweisungen.
const postsCollection: EntityCollection = { slug: "posts", table: "posts", properties: { /* ... */ }, securityRules: [ { operation: "select", access: "public" }, { operations: ["insert", "update", "delete"], ownerField: "author_id" } ]};Funktionsweise
Abschnitt betitelt „Funktionsweise“- Sie definieren
securityRulesfür eine Sammlung rebase schema generateerstellt ein Drizzle-Schema mit aktivierter RLSrebase db pushoderrebase db migratewendet die Richtlinien auf PostgreSQL an- Jede Abfrage wird automatisch nach dem Kontext des aktuellen Benutzers gefiltert
Die Identität des authentifizierten Benutzers ist in SQL verfügbar über:
| Funktion | Rückgabewert |
|---|---|
auth.uid() | Die ID des aktuellen Benutzers |
auth.roles() | Kommagetrennte App-Rollen-IDs |
auth.jwt() | Vollständige JWT-Claims als JSONB |
Diese werden vom Rebase-Backend automatisch pro Transaktion gesetzt.
Praktische Shortcuts
Abschnitt betitelt „Praktische Shortcuts“Eigentümerbasierter Zugriff
Abschnitt betitelt „Eigentümerbasierter Zugriff“Das einfachste Muster — Benutzer können nur auf Zeilen zugreifen, die sie besitzen:
securityRules: [ { operation: "all", ownerField: "user_id" }]Dies erzeugt: USING (user_id = auth.uid())
Öffentlicher Zugriff
Abschnitt betitelt „Öffentlicher Zugriff“Jedem (einschließlich nicht authentifizierten Benutzern) das Lesen erlauben:
securityRules: [ { operation: "select", access: "public" }]Dies erzeugt: USING (true)
Authentifizierter Zugriff
Abschnitt betitelt „Authentifizierter Zugriff“Jedem authentifizierten Benutzer erlauben:
securityRules: [ { operation: "select", access: "authenticated" }]Rollenbasierter Zugriff
Abschnitt betitelt „Rollenbasierter Zugriff“Operationen auf bestimmte Rollen beschränken:
securityRules: [ { operation: "all", roles: ["admin"] }, { operation: "select", roles: ["editor", "viewer"] }]Rohe SQL-Ausdrücke
Abschnitt betitelt „Rohe SQL-Ausdrücke“Für komplexe Logik verwenden Sie using und withCheck:
securityRules: [ { operation: "select", using: "EXISTS (SELECT 1 FROM org_members WHERE org_members.org_id = {org_id} AND org_members.user_id = auth.uid())" }]using— Filtert, welche bestehenden Zeilen sichtbar sind (gilt für SELECT, UPDATE, DELETE)withCheck— Validiert neue Zeilenwerte (gilt für INSERT, UPDATE)
Spaltenreferenzen verwenden die {column_name}-Syntax, die zu der vollständig tabellenqualifizierten Spalte aufgelöst wird.
Kombination von Shortcuts und SQL
Abschnitt betitelt „Kombination von Shortcuts und SQL“Mischen Sie praktische Shortcuts mit rohem SQL:
securityRules: [ // Admins können alles tun { operation: "all", roles: ["admin"], using: "true" }, // Reguläre Benutzer können nur ihre eigenen Zeilen sehen { operation: "select", ownerField: "user_id" }, // Benutzer können einfügen, aber nur für sich selbst { operation: "insert", withCheck: "{user_id} = auth.uid()" }, // Gesperrte Zeilen können nicht aktualisiert werden { operation: "update", mode: "restrictive", using: "{is_locked} = false" }]Permissiv vs. Restriktiv
Abschnitt betitelt „Permissiv vs. Restriktiv“PostgreSQL hat zwei Richtlinienmodi:
- Permissiv (Standard) — Mehrere permissive Richtlinien werden miteinander verknüpft (OR). Wenn eine davon erfolgreich ist, wird der Zugriff gewährt.
- Restriktiv — Restriktive Richtlinien werden miteinander verknüpft (AND). Alle müssen erfolgreich sein.
securityRules: [ // Permissiv: Eigentümer können auf ihre Zeilen zugreifen { operation: "all", ownerField: "user_id" }, // Restriktiv: aber gesperrte Zeilen können nicht aktualisiert werden { operation: "update", mode: "restrictive", using: "{is_locked} = false", withCheck: "{is_locked} = false" }]Operationen
Abschnitt betitelt „Operationen“| Operation | SQL-Äquivalent | Beschreibung |
|---|---|---|
"select" | SELECT | Zeilen lesen |
"insert" | INSERT | Neue Zeilen erstellen |
"update" | UPDATE | Bestehende Zeilen ändern |
"delete" | DELETE | Zeilen entfernen |
"all" | Alle oben genannten | Abkürzung für alle Operationen |
Sie können auch operations (Plural) verwenden, um eine Regel auf mehrere Operationen anzuwenden:
{ operations: ["insert", "update", "delete"], ownerField: "author_id" }Vollständiges SecurityRule-Interface
Abschnitt betitelt „Vollständiges SecurityRule-Interface“interface SecurityRule { name?: string; // Menschlich lesbarer Richtlinienname operation?: SecurityOperation; // Einzelne Operation operations?: SecurityOperation[]; // Mehrere Operationen mode?: "permissive" | "restrictive"; // Standard: "permissive" access?: "public" | "authenticated"; ownerField?: string; // Spalte, die die Benutzer-ID des Eigentümers enthält roles?: string[]; // App-Rollen, für die diese Richtlinie gilt using?: string; // Roher SQL USING-Ausdruck withCheck?: string; // Roher SQL WITH CHECK-Ausdruck}Beispiele
Abschnitt betitelt „Beispiele“Blog-Plattform
Abschnitt betitelt „Blog-Plattform“securityRules: [ // Jeder kann veröffentlichte Beiträge lesen { operation: "select", access: "public", using: "{status} = 'published'" }, // Autoren können ihre eigenen Entwürfe sehen { operation: "select", ownerField: "author_id" }, // Autoren können ihre eigenen Beiträge erstellen und bearbeiten { operations: ["insert", "update"], ownerField: "author_id" }, // Nur Admins können löschen { operation: "delete", roles: ["admin"] }]Mandantenfähiges SaaS
Abschnitt betitelt „Mandantenfähiges SaaS“securityRules: [ { operation: "all", using: "EXISTS (SELECT 1 FROM org_members WHERE org_members.org_id = {org_id} AND org_members.user_id = auth.uid())" }]Anonymer Zugriff (Öffentliche Einfügungen)
Abschnitt betitelt „Anonymer Zugriff (Öffentliche Einfügungen)“Ein häufiges Bedürfnis ist es, nicht authentifizierten Benutzern das Übermitteln von Daten zu ermöglichen — Kontaktformulare, Newsletter-Anmeldungen, öffentliche Anwendungen. Rebase bietet hierfür ein klares Muster.
Empfohlen: access: "public" mit withCheck
Abschnitt betitelt „Empfohlen: access: "public" mit withCheck“const contactMessagesCollection: EntityCollection = { slug: "contact_messages", securityRules: [ // Jeder kann eine Kontaktanfrage senden { operation: "insert", access: "public", withCheck: "true" }, // Nur Admins können Nachrichten lesen, aktualisieren oder löschen { operations: ["select", "update", "delete"], roles: ["admin"] } ], properties: { /* ... */ }};Der access: "public"-Shortcut generiert eine Richtlinie, die die Operation ohne Authentifizierung ermöglicht.
Für Lead-Generierung / Anmeldungen
Abschnitt betitelt „Für Lead-Generierung / Anmeldungen“const leadSignupsCollection: EntityCollection = { slug: "lead_magnet_signups", securityRules: [ // Anonyme Einfügungen erlauben { operation: "insert", access: "public", withCheck: "true" }, // Admins können alle Anmeldungen einsehen { operation: "select", roles: ["admin"] } ], properties: { /* ... */ }};Wie anonyme Anfragen funktionieren
Abschnitt betitelt „Wie anonyme Anfragen funktionieren“Wenn eine Anfrage ohne JWT-Token eingeht, setzt das Rebase-Backend die PostgreSQL-Sitzungsvariablen auf:
| Variable | Wert |
|---|---|
app.user_id | 'anonymous' |
app.user_roles | '' (leer) |
Das bedeutet:
auth.uid()gibt'anonymous'zurückauth.roles()gibt eine leere Zeichenkette zurückaccess: "public"-Richtlinien werden erfolgreich ausgeführt, da sieUSING (true)/WITH CHECK (true)generierenaccess: "authenticated"-Richtlinien schlagen fehl, da sie eine echte Benutzer-ID prüfenownerField-Richtlinien schlagen fehl, da keine Zeileuser_id = 'anonymous'haben wird (es sei denn, dies ist explizit festgelegt)
Fortgeschritten: Rohes SQL für Anonyme
Abschnitt betitelt „Fortgeschritten: Rohes SQL für Anonyme“Wenn Sie eine feinere Kontrolle benötigen, verwenden Sie rohes SQL:
securityRules: [ { operation: "insert", withCheck: "auth.uid() = 'anonymous' OR auth.uid() IS NOT NULL" }]Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- Beziehungen — Fremdschlüssel und Joins
- Entitäts-Callbacks — Lifecycle-Hooks
- Benutzerdefinierte Funktionen — Benutzerdefinierte API-Endpunkte