Firebase Security Rules for Cloud Storage
When developing an application capable of storing files to make them available to other users, you probably found Cloud Storage for Firebase (also called Firebase Storage) as one of the technologies that allow you to do this in a simple, easy and fast way. And if you chose Firebase Storage over the other options, I congratulate you on your choice. But in addition to storing the data in a simple way, we need to ensure that it is safe. And to do that in Firebase Storage, we use security rules the main subject of this article.
The Security Rules
Anyone who has seen/used the Realtime Database Rules, when accessing the Storage Rules tab in the Firebase Console, you will notice that the structure of the security rules is different. That's because Realtime Database rules are organised in a JSON tree, while Cloud Storage rules look like JSON without quotes:
service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } }}
This organisation is used in some of the Google Cloud Platform services such as Cloud Firestore. As with the Realtime Database, Cloud Storage security rules allow you to control read and/or write operations on files. We can also control how these files are structured and what metadata they contain.
To use Cloud Storage security rules, we need to know 2 reserved words: allow
and match
.
Allow
As the name implies, allow
indicates whether an operation (read
or write
) is allowed or not, according to a specified condition (optional). For example:
// If no condition is specified, the rule becomes trueallow read;// Use the if word to specify a condition:allow read: if <condition>;// You can also use a single condition for reading and writingallow read, write: if <condition>;
Simple rules
Remember when we set both Realtime Database rules (.write
and .read
) to true
for testing, leaving the database totally insecure? Well, the equivalent in Cloud Storage is:
service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write; } }}
Note: This will make the Storage public, which means that anyone (even if they are not a user of your application) can store and retrieve files from your Cloud Storage. Use these rules for testing only.
If we wanted to do the opposite of the example above, in the Realtime Database we would put the .write
and .read
in false
. Thus, no one (apart from the project administrators) would have access to the database. In Cloud Storage this can be achieved with the following rules:
service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if false; } }}
And when did we use auth!=null
in the Realtime Database? We allowed the database to be accessed only by registered Firebase Auth users. In Cloud Storage you can also:
service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } }}
Match
As you may have noticed, in all the rules we've written so far, we use the word match. It serves to specify the path where we want to apply each rule. This path can be specified in detail (exact and static path) or through variables (dynamic path).
Exact Path
This is the simplest match, used when we already know the exact path of the file to which we want to apply the rules. For example, to apply rules to the profilePicture.png and thumbnail.png files located in the /images directory:
match /imagens/profilePicture.png { allow write: if <condio>;}match /imagens/miniatura.png { allow write: if <condio>;}
Another way would be splitting the path, creating branches in the tree:
match /imagens { match /profilePicture.png { allow write: if <condio>; } match /miniatura.png { allow write: if <condio>; }}
Dynamic Path (using of variables)
Sometimes we may not know the name of a file or a directory. In these cases, we use variables as we did in the Realtime Database (using the dollar sign $), but here we put the variable name in curly braces. For example:
match /images { //All images in the images directory. match /{ImageName} { allow read: if <condition>; } //All images in the images directory, including subdirectories match /{allImages=**} { allow read: if <other_condition>; }}
Using the rules for validation
In addition to controlling permissions for storing and reading files, we can also validate the files being stored in Cloud Storage. I'll leave just one example to demonstrate the validation, so as not to extend this article too much:
match /{imageId} { allow write: if request.resource.size < 2 * 1024 * 1024 && request.resource.contentType.matches('image/.*')}
With the this rule above, we ensure that the file being stored:
- Does not exceed 2 Megabytes;
- It is an image, regardless of format (jpg, png, bmp, ).
And this was a simple introduction to the Cloud Storage for Firebase Rules. Happy coding!
-
JOIN OUR COMMUNITY ON DISCORD
For more valuable information and trends to help you keep your data safe, join our community
Original Link: https://dev.to/opedroaravena/firebase-security-rules-for-cloud-storage-bl3
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To