How do you keep your custom claims in sync with roles stored in Firebase database

試著忘記壹切 提交于 2019-12-08 03:29:53

问题


This question is lifted from a comment on another thread and I figued that it was a good question that yet didn't have any answer on SO.

How would i link my users in auth, to their specific profiles in the database? (profile contains, full name, usertype, etc.)

The context of the question is referring to the different strategies of storing user auth access logic in the database and/or as custom claims. And how do you maintain those two to be in sync (Is there any function in User Authentication for User Roles?).


回答1:


Custom claims must be set with the admin SDK, which already hints that cloud functions can be utilized to set claims according to your logic.

If the user profile data contains the user type and roles, you can create a trigger for updates on the user object. If you store your roles as an array you can implement a function like this.

functions.firestore.document('users/{uid}').onUpdate((change, context) => {
  const uid = context.params.uid;
  const userBefore = change.before.data();
  const userAfter = change.after.data();

  const hasDifferentNumberOfRoles = userBefore.roles.length !== userAfter.roles.length;
  const hasOtherRoles = userBefore.roles.some((role: string) => userAfter.roles.indexOf(role) === -1);

  if (hasDifferentNumberOfRoles || hasOtherRoles) {
    return admin.auth().setCustomUserClaims(uid, { appRoles: userAfter.roles});  
  }

  return null;
});

This ensures that every time the user roles in data base change, your custom claims auth will also change.

Arrays are convenient for roles since it's easy to query Firestore to find users with certain roles using array-contains and it's also easy to check roles in your database rules as a list.

service cloud.firestore {
  match /databases/{database}/documents {

    match /protected-content/{documentId} {
      allow read: if hasUserRole('admin');
      allow write: if hasUserRole('super-admin');
    }

    function hasUserRole(role) {
      return role in request.auth.token.appRoles;
    }
  }
}

A small side-note about storing your roles in a appRoles attribute on the custom claims, is that it makes in conveniently easy to remove all current roles if you change your structure or want to replace all roles for a user.



来源:https://stackoverflow.com/questions/54394316/how-do-you-keep-your-custom-claims-in-sync-with-roles-stored-in-firebase-databas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!