Reputation: 486
I am designing an application (let's call it a TodoList app) based on VueJs (for the UI) + NodeJs (for the backend, which will run in Google Cloud Platform) + Firestore (for the auth + database).
I have wandered through the huge documentation of Google (sometimes redundant!) to achieve something that should work but I am not sure it's production-proof.
Situation:
I have set some security rules on my Firestore database:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId}/{document=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
so that I don't want any logged users to access data from another user.
Question:
As the Firebase Admin SDK has full privilege on my Firestore database, how can I make sure there won't be any security issues. For now, I am just verifying the accessToken sent in the request to my backend, but ... something makes me feel wrong with this!
Code:
On client-side:
auth.onAuthStateChanged((user) => {
if (user) {
// Save the user credentials
}
}
On server-side:
// idToken comes from the client app (shown above)
// ...
admin.auth().verifyIdToken(idToken)
.then(function(decodedToken) {
var uid = decodedToken.uid;
// Retrieve or add some data in /users/{userId}/{document=**}
}).catch(function(error) {
// Handle error
});
As you can see, once I validate the accessToken and retrieve the uid, I can do anything on my database.
References
Thanks for your help!
Upvotes: 23
Views: 5991
Reputation: 6742
The admin SDK will always have full access to the database.
Since the client is never accessing Firebase directly, you should totally disable access to all documents. Your API will still have access
match /{document=**} {
allow read, write: if false;
}
Upvotes: 31
Reputation: 1
I think after verify access token from client-side, you can send uid in resource of firestore-admin, and firestore rules would like this:
allow read, write: if request.resource.data.uid == userId;
Upvotes: 0