Firebase Firestore安全规则中的多字段验证

lf5gs5x2  于 2023-04-22  发布在  其他
关注(0)|答案(1)|浏览(178)

我为Firestore数据库的GameAdmins集合编写了以下安全规则:

match /GameAdmins/{adminId} {
      function validAdminData() {
        let keys = request.resource.data.keys().toSet();
        let allowedKeys = ['admin', 'superAdmin'].toSet();
        let data = request.resource.data;
        
        return (keys == allowedKeys) && (data.admin is bool) && (data.superAdmin is bool);
      }
      
      allow create, update: if isSuperAdmin() && validAdminData();
      allow delete: if isSuperAdmin();
    }

因此,在创建或更新文档时,它只允许两个布尔字段adminsuperAdmin。这个方法很容易编写,因为它只有两个字段。当我想为一个有很多字段的不同集合编写相同的方法时,就会变得困难,因为我必须编写键列表并检查每个字段的类型。
我想在数据库中保存虚拟数据,这样我就可以从那里得到允许的密钥列表。但是我仍然必须分别检查它们的每种类型。
有没有更好的方法来检查列表的关键字和他们的类型与更少的代码量?

a14dhokn

a14dhokn1#

我写了一些函数,它们不是完全动态的,但现在可以工作。

function validateType(data, type) {
      return (
        (type == 'string' && data is string) ||
        (type == 'int' && data is int) ||
        (type == 'bool' && data is bool) ||
        (type == 'timestamp' && data is timestamp) ||
        (type == 'list' && data is list)
      );
    }
    
    function validateEachField(data, model) {
      let keys = model.keys();
      let n = keys.size() - 1;
      
      return (
        (n <= 0 || validateType(data[keys[0]], model[keys[0]])) &&
        (n <= 1 || validateType(data[keys[1]], model[keys[1]])) &&
        (n <= 2 || validateType(data[keys[2]], model[keys[2]])) &&
        (n <= 3 || validateType(data[keys[3]], model[keys[3]])) &&
        (n <= 4 || validateType(data[keys[4]], model[keys[4]])) &&
        (n <= 5 || validateType(data[keys[5]], model[keys[5]])) &&
        (n <= 6 || validateType(data[keys[6]], model[keys[6]])) &&
        (n <= 7 || validateType(data[keys[7]], model[keys[7]])) &&
        (n <= 8 || validateType(data[keys[8]], model[keys[8]])) &&
        (n <= 9 || validateType(data[keys[9]], model[keys[9]]))
      );
    }
    
    function validateData(collection) {
      let model = get(/databases/$(database)/documents/DataModels/$(collection)/$(collection)).data;
      let keys = request.resource.data.keys().toSet();
      let allowedKeys = model.keys().toSet();
      return keys == allowedKeys && validateEachField(request.resource.data, model);
    }

唯一的问题似乎是,当字段数量增加时,我可能需要在validateEachField函数中添加更多行,并在未来在validateType函数中添加对更多类型的支持。

相关问题