问题
Initial situation:
I am developing an app (iOS, Android, Web App) that primarily uses Firebase Auth Email & Password to authorize my users and manage permissions.
There are complex configuration options for the security and access settings that can be individually set for each user. There are also premade roles (e.g. admin, manager, etc.). However, these are only templates and don't need to be used by the person who manages the user accounts. The permissions can be customized for each user and the whole application.
My approach:
Using Firebase Auth custom claims
Because of the very customizable permission model, I thought of giving every permission a number like this:
2000: Calendar (Full access) 2001: Calendar (View access) 2002: Calendar (Create access) 2003: Calendar (Edit access) 2004: Calendar (Delete access)
Then I thought it would be a great idea to store the permissions that are
true
as aboolean
(because of the smaller size than anInteger
) in the custom claims of theuser
like this:// User with permissions to view the calendar, create and edit events but not authorized to delete: 'claims': { '2001': true, '2002': true, '2003': true } // User with full access to the calendar 'claims': { '2000': true }
The permissions are also stored in Firebase Cloud Firestore.
Cloud Firestore > users > [unique_user_id] > permissions
Checking permissions on the clients side
When the user opens the app, on the first load the system performs two reads to Firebase Cloud Firestore to retrieve all of the current metadata to set the app up properly. This data is saved locally. It contains metadata to display everything correctly and also the user's permissions. This way the UI is already preventing the user from accessing content that should not be visible or taking actions (create, edit, delete).
Checking permissions on the server-side via security rules of Firebase Cloud Firestore
Because client-side operations might be manipulated by the user or the permissions of an individual user change while the user is using the application, there need to be some advanced security instruments that improve the overall safety of the application. This should be done on the server-side via Cloud Functions and the security rules of Firebase Cloud Firestore.
A security rule could look like this:
service cloud.firestore { match /databases/{database}/{project_id} { match /calendar/{event} { allow read: if request.auth.token.2000 == true || request.auth.token.2001 == true; allow write: if request.auth.token.2000 == true || request.auth.token.2002 == true; allow update: if request.auth.token.2000 == true || request.auth.token.2003 == true; allow delete: if request.auth.token.2000 == true || request.auth.token.2004 == true; }
}
I could do all of this also with a Cloud Function that checks the user's permissions before every action to the database. However, this would result in another read for the permission of the user for every action that was performed. This would result in a higher amount on my Firebase bill. I try to avoid this!
Question
What do you think about this, is there a better solution for it? I am not sure if this is really it.
I also use Microsoft as a provider to authorize the user instead of creating a new account. Will this also work with those thate sign in via Microsoft?
来源:https://stackoverflow.com/questions/62922737/using-firebase-auth-custom-claims-for-custom-permissions