Dieser Leitfaden baut auf dem Erlernen der Kernsyntax des Sprachleitfadens „Firebase Security Rules“ auf und zeigt, wie Sie Bedingungen zu Ihren Firebase Security Rules für Cloud Storage hinzufügen.
Der Hauptbaustein der Cloud Storage-Sicherheitsregeln ist die Bedingung . Eine Bedingung ist ein boolescher Ausdruck, der bestimmt, ob ein bestimmter Vorgang zugelassen oder verweigert werden soll. Bei Grundregeln funktioniert die Verwendung true
und false
Literale als Bedingungen vollkommen gut. Aber die Firebase Security Rules for Cloud Storage-Sprache bietet Ihnen Möglichkeiten, komplexere Bedingungen zu schreiben, die Folgendes können:
- Überprüfen Sie die Benutzerauthentifizierung
- Eingehende Daten validieren
Authentifizierung
Firebase Security Rules für Cloud Storage lässt sich in Firebase Authentication integrieren, um eine leistungsstarke benutzerbasierte Authentifizierung für Cloud Storage bereitzustellen. Dies ermöglicht eine detaillierte Zugriffskontrolle basierend auf Ansprüchen eines Firebase-Authentifizierungstokens.
Wenn ein authentifizierter Benutzer eine Anfrage an Cloud Storage durchführt, wird die Variable request.auth
mit der uid
des Benutzers ( request.auth.uid
) sowie den Ansprüchen des Firebase Authentication JWT ( request.auth.token
) gefüllt.
Darüber hinaus werden bei Verwendung der benutzerdefinierten Authentifizierung zusätzliche Ansprüche im Feld request.auth.token
angezeigt.
Wenn ein nicht authentifizierter Benutzer eine Anfrage ausführt, ist die Variable request.auth
null
.
Unter Verwendung dieser Daten gibt es mehrere gängige Möglichkeiten, die Authentifizierung zum Sichern von Dateien zu verwenden:
- Öffentlich:
request.auth
ignorieren - Authentifiziert privat: Stellen Sie sicher, dass
request.auth
nichtnull
ist - Privater Benutzer: Überprüfen Sie, ob
request.auth.uid
einer Pfad-uid
entspricht - Gruppe privat: Überprüfen Sie, ob die Ansprüche des benutzerdefinierten Tokens mit einem ausgewählten Anspruch übereinstimmen, oder lesen Sie die Dateimetadaten, um festzustellen, ob ein Metadatenfeld vorhanden ist
Öffentlich
Jede Regel, die den request.auth
Kontext nicht berücksichtigt, kann als public
Regel betrachtet werden, da sie den Authentifizierungskontext des Benutzers nicht berücksichtigt. Diese Regeln können nützlich sein, um öffentliche Daten wie Spielressourcen, Sounddateien oder andere statische Inhalte anzuzeigen.
// Anyone to read a public image if the file is less than 100kB // Anyone can upload a public file ending in '.txt' match /public/{imageId} { allow read: if resource.size < 100 * 1024; allow write: if imageId.matches(".*\\.txt"); }
Authentifizierter Privater
In bestimmten Fällen möchten Sie möglicherweise, dass Daten für alle authentifizierten Benutzer Ihrer Anwendung sichtbar sind, nicht jedoch für nicht authentifizierte Benutzer. Da die Variable request.auth
für alle nicht authentifizierten Benutzer null
ist, müssen Sie lediglich prüfen, ob die Variable „ request.auth
vorhanden ist, um eine Authentifizierung anzufordern:
// Require authentication on all internal image reads match /internal/{imageId} { allow read: if request.auth != null; }
Benutzer privat
Der mit Abstand häufigste Anwendungsfall für request.auth
wird darin bestehen, einzelnen Benutzern detaillierte Berechtigungen für ihre Dateien zu gewähren: vom Hochladen von Profilbildern bis zum Lesen privater Dokumente.
Da Dateien in Cloud Storage über einen vollständigen „Pfad“ zur Datei verfügen, ist alles, was erforderlich ist, um eine von einem Benutzer kontrollierte Datei zu erstellen, eine eindeutige, benutzeridentifizierende Information im Dateinamen-Präfix (z. B. die uid
des Benutzers), die überprüft werden kann wenn die Regel ausgewertet wird:
// Only a user can upload their profile picture, but anyone can view it match /users/{userId}/profilePicture.png { allow read; allow write: if request.auth.uid == userId; }
Gruppe privat
Ein weiterer ebenso häufiger Anwendungsfall besteht darin, Gruppenberechtigungen für ein Objekt zuzulassen, beispielsweise um mehreren Teammitgliedern die Zusammenarbeit an einem gemeinsamen Dokument zu ermöglichen. Hierfür gibt es mehrere Ansätze:
- Erstellen Sie ein benutzerdefiniertes Firebase-Authentifizierungstoken, das zusätzliche Informationen zu einem Gruppenmitglied enthält (z. B. eine Gruppen-ID).
- Fügen Sie Gruppeninformationen (z. B. eine Gruppen-ID oder eine Liste autorisierter
uid
) in die Dateimetadaten ein
Sobald diese Daten im Token oder in den Dateimetadaten gespeichert sind, kann innerhalb einer Regel darauf verwiesen werden:
// 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; }
Bewertung anfordern
Uploads, Downloads, Metadatenänderungen und Löschungen werden anhand der an Cloud Storage gesendeten request
ausgewertet. Zusätzlich zur eindeutigen ID des Benutzers und der Firebase-Authentifizierungsnutzlast im Objekt request.auth
, wie oben beschrieben, enthält die request
den Dateipfad, in dem die Anforderung ausgeführt wird, die Zeit, zu der die Anforderung empfangen wird, und den neuen resource
, wenn Die Anfrage ist ein Schreibvorgang.
Das request
enthält außerdem die eindeutige ID des Benutzers und die Firebase-Authentifizierungsnutzlast im Objekt „ request.auth
“, was im Abschnitt „Benutzerbasierte Sicherheit“ der Dokumentation näher erläutert wird.
Eine vollständige Liste der Eigenschaften im request
finden Sie unten:
Eigentum | Typ | Beschreibung |
---|---|---|
auth | map<string, string> | Wenn ein Benutzer angemeldet ist, werden uid , die eindeutige ID des Benutzers, und token , eine Karte der Firebase Authentication JWT-Ansprüche, bereitgestellt. Andernfalls ist es null . |
params | map<string, string> | Karte, die die Abfrageparameter der Anfrage enthält. |
path | Weg | Ein path , der den Pfad darstellt, auf dem die Anforderung ausgeführt wird. |
resource | map<string, string> | Der neue Ressourcenwert, der nur bei write vorhanden ist. |
time | Zeitstempel | Ein Zeitstempel, der die Serverzeit angibt, zu der die Anfrage ausgewertet wird. |
Ressourcenbewertung
Beim Auswerten von Regeln möchten Sie möglicherweise auch die Metadaten der Datei auswerten, die hochgeladen, heruntergeladen, geändert oder gelöscht wird. Auf diese Weise können Sie komplexe und leistungsstarke Regeln erstellen, die beispielsweise nur das Hochladen von Dateien mit bestimmten Inhaltstypen zulassen oder nur das Löschen von Dateien ab einer bestimmten Größe zulassen.
Firebase-Sicherheitsregeln für Cloud Storage stellen Dateimetadaten im resource
bereit, das Schlüssel/Wert-Paare der Metadaten enthält, die in einem Cloud Storage-Objekt angezeigt werden. Diese Eigenschaften können bei read
oder write
überprüft werden, um die Datenintegrität sicherzustellen.
Bei write
(z. B. Uploads, Metadatenaktualisierungen und Löschvorgängen) haben Sie zusätzlich zum resource
, das Dateimetadaten für die Datei enthält, die derzeit im Anforderungspfad vorhanden ist, auch die Möglichkeit, das Objekt request.resource
zu verwenden. die eine Teilmenge der Dateimetadaten enthält, die geschrieben werden sollen, wenn das Schreiben zulässig ist. Sie können diese beiden Werte verwenden, um die Datenintegrität sicherzustellen oder Anwendungsbeschränkungen wie Dateityp oder -größe durchzusetzen.
Eine vollständige Liste der Eigenschaften im resource
finden Sie unten:
Eigentum | Typ | Beschreibung |
---|---|---|
name | Zeichenfolge | Der vollständige Name des Objekts |
bucket | Zeichenfolge | Der Name des Buckets, in dem sich dieses Objekt befindet. |
generation | int | Die Google Cloud Storage-Objektgenerierung dieses Objekts. |
metageneration | int | Die Google Cloud Storage-Objektmetagenerierung dieses Objekts. |
size | int | Die Größe des Objekts in Bytes. |
timeCreated | Zeitstempel | Ein Zeitstempel, der den Zeitpunkt angibt, zu dem ein Objekt erstellt wurde. |
updated | Zeitstempel | Ein Zeitstempel, der den Zeitpunkt angibt, zu dem ein Objekt zuletzt aktualisiert wurde. |
md5Hash | Zeichenfolge | Ein MD5-Hash des Objekts. |
crc32c | Zeichenfolge | Ein crc32c-Hash des Objekts. |
etag | Zeichenfolge | Das diesem Objekt zugeordnete Etag. |
contentDisposition | Zeichenfolge | Die diesem Objekt zugeordnete Inhaltsdisposition. |
contentEncoding | Zeichenfolge | Die diesem Objekt zugeordnete Inhaltskodierung. |
contentLanguage | Zeichenfolge | Die diesem Objekt zugeordnete Inhaltssprache. |
contentType | Zeichenfolge | Der diesem Objekt zugeordnete Inhaltstyp. |
metadata | map<string, string> | Schlüssel/Wert-Paare zusätzlicher, vom Entwickler angegebener benutzerdefinierter Metadaten. |
request.resource
enthält alle diese mit Ausnahme von generation
, metageneration
, etag
, timeCreated
und updated
.
Erweitern Sie mit Cloud Firestore
Sie können auf Dokumente im Cloud Firestore zugreifen, um andere Autorisierungskriterien auszuwerten.
Mit den Funktionen firestore.get()
und firestore.exists()
können Ihre Sicherheitsregeln eingehende Anfragen anhand von Dokumenten in Cloud Firestore bewerten. Die Funktionen firestore.get()
und firestore.exists()
erwarten beide vollständig angegebene Dokumentpfade. Wenn Sie Variablen verwenden, um Pfade für firestore.get()
und firestore.exists()
zu erstellen, müssen Sie Variablen mithilfe der $(variable)
-Syntax explizit maskieren.
Im folgenden Beispiel sehen wir eine Regel, die den Lesezugriff auf Dateien auf Benutzer beschränkt, die Mitglieder bestimmter Clubs sind.
service firebase.storage { match /b/{bucket}/o { match /users/{club}/files/{fileId} { allow read: if club in firestore.get(/databases/(default)/documents/users/$(request.auth.id)).memberships } } }Im nächsten Beispiel können nur die Freunde eines Benutzers seine Fotos sehen.
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/photos/{fileId} { allow read: if firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id)) } } }
Sobald Sie Ihre ersten Cloud Storage-Sicherheitsregeln erstellt und gespeichert haben, die diese Cloud Firestore-Funktionen verwenden, werden Sie in der Firebase-Konsole oder der Firebase-CLI aufgefordert, Berechtigungen zum Verbinden der beiden Produkte zu aktivieren.
Sie können die Funktion deaktivieren, indem Sie eine IAM-Rolle entfernen, wie unter Verwalten und Bereitstellen von Firebase-Sicherheitsregeln beschrieben.
Daten validieren
Firebase-Sicherheitsregeln für Cloud Storage können auch zur Datenvalidierung verwendet werden, einschließlich der Validierung von Dateinamen und -pfad sowie Dateimetadateneigenschaften wie contentType
und size
.
service firebase.storage { match /b/{bucket}/o { match /images/{imageId} { // Only allow uploads of any image file that's less than 5MB allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*'); } } }
Benutzerdefinierte Funktionen
Wenn Ihre Firebase-Sicherheitsregeln komplexer werden, möchten Sie möglicherweise Sätze von Bedingungen in Funktionen einschließen, die Sie in Ihrem Regelsatz wiederverwenden können. Sicherheitsregeln unterstützen benutzerdefinierte Funktionen. Die Syntax für benutzerdefinierte Funktionen ähnelt ein wenig der von JavaScript, die Funktionen von Firebase Security Rules sind jedoch in einer domänenspezifischen Sprache geschrieben, die einige wichtige Einschränkungen aufweist:
- Funktionen können nur eine einzige
return
Anweisung enthalten. Sie dürfen keine zusätzliche Logik enthalten. Sie können beispielsweise keine Schleifen ausführen oder externe Dienste aufrufen. - Funktionen können automatisch auf Funktionen und Variablen aus dem Bereich zugreifen, in dem sie definiert sind. Beispielsweise hat eine im
service firebase.storage
definierte Funktion Zugriff auf dieresource
und nur für Cloud Firestore auf integrierte Funktionen wieget()
undexists()
. - Funktionen können andere Funktionen aufrufen, dürfen jedoch nicht rekursiv sein. Die Gesamttiefe des Aufrufstapels ist auf 10 begrenzt.
- In Version
rules2
können Funktionen Variablen mithilfe des Schlüsselwortslet
definieren. Funktionen können eine beliebige Anzahl von Let-Bindungen haben, müssen jedoch mit einer Return-Anweisung enden.
Eine Funktion wird mit dem Schlüsselwort function
definiert und akzeptiert null oder mehr Argumente. Beispielsweise möchten Sie möglicherweise die beiden in den obigen Beispielen verwendeten Arten von Bedingungen in einer einzigen Funktion kombinieren:
service firebase.storage {
match /b/{bucket}/o {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /images/{imageId} {
allow read, write: if signedInOrPublic();
}
match /mp3s/{mp3Ids} {
allow read: if signedInOrPublic();
}
}
}
Durch die Verwendung von Funktionen in Ihren Firebase-Sicherheitsregeln werden diese leichter wartbar, wenn die Komplexität Ihrer Regeln zunimmt.
Nächste Schritte
Nach dieser Erörterung der Bedingungen verfügen Sie über ein umfassenderes Verständnis der Regeln und sind bereit für Folgendes:
Erfahren Sie, wie Sie mit Kernanwendungsfällen umgehen und lernen Sie den Workflow zum Entwickeln, Testen und Bereitstellen von Regeln kennen:
- Schreiben Sie Regeln, die häufig vorkommende Szenarien berücksichtigen.
- Bauen Sie Ihr Wissen aus, indem Sie Situationen durchgehen, in denen Sie unsichere Regeln erkennen und vermeiden müssen.
- Testen Sie Regeln mit dem Cloud Storage-Emulator und der speziellen Testbibliothek für Sicherheitsregeln .
- Sehen Sie sich die verfügbaren Methoden zum Bereitstellen von Regeln an.