Пользовательские утверждения должны быть установлены с помощью Admin SDK, который уже намекает на то, что облачные функции могут использоваться для установки утверждений в соответствии с вашей логикой.
Если данные профиля пользователя содержат тип и роли пользователя, вы можетесоздать триггер для обновлений объекта пользователя.Если вы храните свои роли в виде массива, вы можете реализовать функцию, подобную этой.
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;
});
Это гарантирует, что каждый раз, когда меняются роли пользователей в базе данных, ваш пользовательский запрос утверждений также будет меняться.
Массивы удобны для ролей, поскольку с помощью array-contains
можно легко запросить Firestore для поиска пользователей с определенными ролями, а также легко проверить роли в правилах базы данных в виде списка .
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;
}
}
}
Небольшое замечание о сохранении ваших ролей в атрибуте appRoles
в настраиваемых утверждениях заключается в том, что с ним удобно легко удалить все текущие роли, если вы измените свою структуру или хотите заменить все роли для пользователя.