Node.js: whitelisting/redaction 个数据库条目

Node.js: whitelisting/redaction of database entries

从节点,我访问一个数据库,其中包含

animals: [
{
  name: monkey,
  diet: banana,
  tame: false,
},
{
  name: donkey,
  diet: carrot,
  tame: true,
}
// [...]
]

我想将大部分数据的访问权限授予客户端,但要确保 tame 属性 公开。

使用节点和 lodash's pick(),我可以以某种方式将数据列入白名单,例如,

// retrieve data
// [...]

// whitelist
return {
   name: _.pick(animal, 'name'),
   diet: _.pick(animal, 'diet'),
};

但这有点乏味,特别是如果密钥的选择取决于其他因素(例如,试图访问数据的用户)。

什么是好的白名单/redaction patterns/modules 节点?

这在很大程度上取决于您使用的数据库。大多数数据库只允许您 select 查询本身中的特定 columns/fields。 MongoDB 也这样做。

如果您使用 mongoose,您实际上可以为每个模型强制执行此操作:

function filter(document, animal) {
    delete animal.tame;
    return animal;
};

var options = {
    toJSON: {transform: filter},
    toObject: {transform: filter}
};

var animalSchema = new Schema({
       name: { type: String, trim: true, required: true },
       tame: { type: boolean, required: true },
       secret: { type: String, required: true, select: false }
    },options);


var Animal = mongoose.model('Animal', animalSchema);

var dog = new Animal({name:"rex", tame:true, secret:"rexrex"});

dog.save();

dog.toJSON(); // will not have "tame" property
dog.toJSON({transform: filter}) // dynamic filter

dog.toObject(); // will not have "tame" property

Animal.findOne(); // result objects will not have "secret" property

如您所见,您可以:

  1. 设置转换函数以在导出到 json 或对象时在文档上执行。
  2. select:false 标记一个字段,它不会出现在任何基于 mongoose 模型的查询中。 (不过您仍然可以执行自定义查询。)

如果您要处理大量对象,请考虑写一个 Transform Stream。那么你可以:

Animal.find().stream().pipe(myTransformStream).pipe(clientResponse)