Firebase Security Rules können Sie den Zugriff auf Ihre gespeicherten Daten steuern. Die flexible Regelsyntax bedeutet, dass Sie Regeln erstellen können, die mit allem übereinstimmen, von allen Schreibvorgängen über die gesamte Datenbank bis hin zu Vorgängen in einem bestimmten Dokument.
In diesem Leitfaden werden einige der einfacheren Anwendungsfälle beschrieben, die Sie beim Einrichten Ihrer Anwendung und zum Schutz Ihrer Daten berücksichtigen können. Bevor Sie jedoch mit dem Erstellen von Regeln beginnen, sollten Sie mehr über die Sprache erfahren, in der sie geschrieben sind, und über ihr Verhalten.
Wenn Sie auf Ihre Regeln zugreifen und sie aktualisieren möchten, folgen Sie der Anleitung unter Firebase Security Rules verwalten und bereitstellen.
Standardregeln: Sperrmodus
Wenn Sie eine Datenbank- oder Speicherinstanz in der Firebase Console erstellen, können Sie festlegen, ob Firebase Security Rules den Zugriff auf Ihre Daten einschränkt (Gesperrter Modus) oder allen Zugriff gewährt (Testmodus). In Cloud Firestore und Realtime Database wird der Zugriff für alle Nutzer gemäß den Standardregeln für den gesperrten Modus abgelehnt. In Cloud Storage können nur authentifizierte Nutzer auf die Speicher-Buckets zugreifen.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Realtime Database
{
"rules": {
".read": false,
".write": false
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Regeln für die Entwicklungsumgebung
Während Sie an Ihrer App arbeiten, möchten Sie möglicherweise relativ freien oder uneingeschränkten Zugriff auf Ihre Daten haben. Denken Sie nur daran, Ihre Rules zu aktualisieren, bevor Sie Ihre App in der Produktion bereitstellen. Wenn Sie Ihre Anwendung bereitstellen, ist sie öffentlich zugänglich, selbst wenn Sie sie nicht gestartet haben.
Denken Sie daran, dass Firebase Clients direkten Zugriff auf Ihre Daten gewährt und Firebase Security Rules die einzige Maßnahme ist, die den Zugriff für böswillige Nutzer blockiert. Die Definition von Regeln getrennt von der Produktlogik bietet eine Reihe von Vorteilen: Clients sind nicht für die Durchsetzung der Sicherheit verantwortlich, fehlerhafte Implementierungen gefährden Ihre Daten nicht und Sie verlassen sich nicht auf einen Zwischenserver, um Daten vor der Welt zu schützen.
Alle authentifizierten Nutzer
Wir empfehlen zwar nicht, Ihre Daten für alle angemeldeten Nutzer zugänglich zu machen, es kann jedoch hilfreich sein, den Zugriff für alle authentifizierten Nutzer festzulegen, während Sie Ihre App entwickeln.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
Realtime Database
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Produktionsreife Regeln
Achten Sie bei der Vorbereitung der Bereitstellung Ihrer App darauf, dass Ihre Daten geschützt sind und dass Ihren Nutzern der Zugriff ordnungsgemäß gewährt wird. Mit Authentication können Sie einen nutzerbasierten Zugriff einrichten und direkt aus Ihrer Datenbank lesen, um einen datengestützten Zugriff einzurichten.
Sie sollten beim Strukturieren Ihrer Daten Regeln festlegen, da sich die Art und Weise, wie Sie Ihre Regeln einrichten, darauf auswirkt, wie Sie den Zugriff auf Daten auf verschiedenen Pfaden einschränken.
Zugriff nur für Rechteinhaber
Diese Regeln beschränken den Zugriff ausschließlich auf den authentifizierten Inhaber der Inhalte. Die Daten sind nur für einen Nutzer lesbar und beschreibbar. Der Datenpfad enthält die ID des Nutzers.
Wann diese Regel funktioniert:Diese Regel eignet sich gut, wenn Daten nach Nutzer silotiert sind, d. h. wenn der einzige Nutzer, der auf die Daten zugreifen muss, derselbe ist, der die Daten erstellt hat.
Wenn diese Regel nicht funktioniert:Diese Regel funktioniert nicht, wenn mehrere Nutzer dieselben Daten schreiben oder lesen müssen. In diesem Fall überschreiben Nutzer Daten oder können nicht auf von ihnen erstellte Daten zugreifen.
So richten Sie diese Regel ein:Erstellen Sie eine Regel, die bestätigt, dass der Nutzer, der den Zugriff zum Lesen oder Schreiben von Daten anfordert, der Inhaber dieser Daten ist.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /some_collection/{userId}/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == userId
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
Cloud Storage
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
Gemischter öffentlicher und privater Zugriff
Diese Regel ermöglicht jedem beliebigen Nutzer das Lesen eines Datasets, schränkt aber die Möglichkeit ein, Daten unter einem bestimmten Pfad zum authentifizierten Rechteinhaber zu erstellen oder zu ändern.
Wann diese Regel funktioniert:Diese Regel funktioniert gut bei Anwendungen, die öffentlich lesbare Elemente benötigen, bei denen aber der Bearbeitungszugriff auf die Eigentümer dieser Elemente beschränkt werden muss. Beispiel: eine Chat-App oder ein Blog.
Wenn diese Regel nicht funktioniert:Wie die Regel nur für Rechteinhaber funktioniert auch dieser Regelsatz nicht, wenn mehrere Nutzer dieselben Daten bearbeiten müssen. Die Nutzer überschreiben letztendlich die Daten der anderen.
So richten Sie diese Regel ein:Erstellen Sie eine Regel, die den Lesezugriff für alle Nutzer (oder alle authentifizierten Nutzer) aktiviert, und bestätigen Sie, dass der Nutzer, der Daten schreibt, der Inhaber ist.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow public read access, but only content owners can write
match /some_collection/{document} {
// Allow public reads
allow read: if true
// Allow creation if the current user owns the new document
allow create: if request.auth.uid == request.resource.data.author_uid;
// Allow updates by the owner, and prevent change of ownership
allow update: if request.auth.uid == request.resource.data.author_uid
&& request.auth.uid == resource.data.author_uid;
// Allow deletion if the current user owns the existing document
allow delete: if request.auth.uid == resource.data.author_uid;
}
}
}
Realtime Database
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path": {
"$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
Attribut- und rollenbasierter Zugriff
Damit diese Regel funktioniert, müssen Sie Attribute in Ihren Daten definieren und Nutzern zuweisen. Firebase Security Rules die Anfrage mit den Daten aus Ihrer Datenbank oder den Metadaten der Datei vergleichen, um den Zugriff zu bestätigen oder abzulehnen.
Ein Anwendungsfall:Wenn Sie Nutzern eine Rolle zuweisen, können Sie mit dieser Regel den Zugriff basierend auf Rollen oder bestimmten Nutzergruppen ganz einfach einschränken. Wenn Sie beispielsweise Noten speichern, können Sie der Gruppe „Schüler“ (nur Inhalte lesen), der Gruppe „Lehrkräfte“ (Lesen und Schreiben im Fach) und der Gruppe „Leiter“ (alle Inhalte lesen) unterschiedliche Zugriffsebenen zuweisen.
Wenn diese Regel nicht funktioniert:In Realtime Database und Cloud Storage können Ihre Regeln nicht die get()
-Methode verwenden, die in Cloud Firestore-Regeln enthalten ist.
Daher müssen Sie die Metadaten Ihrer Datenbank oder Datei so strukturieren, dass sie die Attribute widerspiegeln, die Sie in Ihren Regeln verwenden.
So richten Sie diese Regel ein:Fügen Sie in Cloud Firestore ein Feld in die Dokumente Ihrer Nutzer ein, das Sie lesen können. Strukturieren Sie dann Ihre Regel so, dass dieses Feld gelesen und der Zugriff bedingt gewährt wird. Erstellen Sie in Realtime Database einen Datenpfad, der die Nutzer Ihrer App definiert und ihnen eine Rolle in einem untergeordneten Knoten zuweist.
Sie können auch benutzerdefinierte Ansprüche in Authentication einrichten und diese Informationen dann aus der Variablen auth.token
in einer beliebigen Firebase Security Rules abrufen.
Datendefinierte Attribute und Rollen
Diese Regeln funktionieren nur in Cloud Firestore und Realtime Database.
Cloud Firestore
Denken Sie daran, dass Ihnen bei jeder Regel, die einen Lesevorgang enthält, wie die unten aufgeführten, ein Lesevorgang in Cloud Firestore in Rechnung gestellt wird.
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, Check a boolean `admin` attribute
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"${subpath}": {
//
".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
".read": true
}
}
}
}
Attribute und Rollen für benutzerdefinierte Ansprüche
Wenn Sie diese Regeln implementieren möchten, richten Sie benutzerdefinierte Ansprüche in Firebase Authentication ein und nutzen Sie diese dann in Ihren Regeln.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an admin claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Create a custom claim for each role or group
// you want to leverage
".write": "auth.uid !== null && auth.token.writer === true",
".read": "auth.uid !== null && auth.token.reader === true"
}
}
}
}
Cloud Storage
service firebase.storage {
// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
allow read: if resource.metadata.owner == request.auth.token.groupId;
allow write: if request.auth.token.groupId == groupId;
}
}
Untermieterattribute
Wenn Sie diese Regeln implementieren möchten, richten Sie die Mehrfachnutzung in der Google Cloud Identity Platform (GCIP) ein und verwenden Sie den Tenant dann in Ihren Regeln. In den folgenden Beispielen sind Schreibvorgänge von einem Nutzer in einem bestimmten Mandanten zulässig, z. B. tenant2-m6tyz
.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For tenant-based access control, check for a tenantID
allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
allow read: true;
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Only allow reads and writes if user belongs to a specific tenant
".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
".read": "auth.uid !== null
}
}
}
}
Cloud Storage
service firebase.storage {
// Only allow reads and writes if user belongs to a specific tenant
match /files/{tenantId}/{fileName} {
allow read: if request.auth != null;
allow write: if request.auth.token.firebase.tenant == tenantId;
}
}