Mongooseencryption中间件在聚合之后不会调用

我有一个带有“mongoose-encryption”插件的mongoose模式,例如:

let someSchema = new Schema({name, age}); someSchema.plugin(mongoose-encryption, { encryptionKey: 'eKey', signingKey: 'sKey', encryptedFields: ['age'], decryptPostSave: false }); 

启动模型和存储库后,我尝试聚合一些查询:

 let aggregation = []; // just return all the docs. someModel.aggregate(aggregation, (err, persons) => { return persons; }); 

因此,我仍然得到encryption的年龄字段,很less有人读到“聚合之后”调用“init”事件的'post'方法(如这里所解释的 – Mongoose Middleware Docs )。

有没有一个好的解决scheme? 或任何其他解决方法?

  • 数据必须encryption。

  • 聚合也是必需的(在现实生活中 – 查找其他collections)

由于我没有find更好的答案,我改变了我的代码(不幸的是解决方法),以便自己解密对象 – 在聚合完成之后,使用mongooseencryption代码进行解密。

大部分的代码是从GitHub(在我的代码中称为decryptOne)中取得的: 解密同步encryption的mongooseencryptionfunction

“棘手”的事情是解密内部查找值 – 内部文件也有应该被解密的“_ct”字段。

 let lookup: { [innerField: string]: string[]; } = { user: ['bio'] }; this.decryptAggregation(aggregationResult, lookup); 

我的函数在解密后获取已知查找集合和其所需字段的字典。 在这个例子中,其他名为用户的集合及其encryption的字段就是他的生物。

 decryptAggregation(res: any[], innerLookup: { [innerField: string]: string[]; }) { for (let doc of res) { this.decryptSync(doc, innerLookup); } } private decryptSync(doc: any, innerLookup: { [innerField: string]: string[]; }) { this.decryptOne(doc, this.encryptedFields); for (let innerObj in innerLookup) { if (innerLookup.hasOwnProperty(innerObj)) { this.decryptOne(doc[innerObj], innerLookup[innerObj]); } } }; private decryptOne(doc: any, fields: string[]) { let ct, ctWithIV, decipher, iv, idString, decryptedObject, decryptedObjectJSON, decipheredVal; if (doc._ct) { ctWithIV = doc._ct.hasOwnProperty('buffer') ? doc._ct.buffer : doc._ct; iv = ctWithIV.slice(this.VERSION_LENGTH, this.VERSION_LENGTH + this.IV_LENGTH); ct = ctWithIV.slice(this.VERSION_LENGTH + this.IV_LENGTH, ctWithIV.length); decipher = crypto.createDecipheriv(this.ENCRYPTION_ALGORITHM, this.encryptionKey, iv); try { decryptedObjectJSON = decipher.update(ct, undefined, 'utf8') + decipher.final('utf8'); decryptedObject = JSON.parse(decryptedObjectJSON); } catch (err) { if (doc._id) { idString = doc._id.toString(); } else { idString = 'unknown'; } throw new Error('Error parsing JSON during decrypt of ' + idString + ': ' + err); } fields.forEach((field) => { decipheredVal = mpath.get(field, decryptedObject); //JSON.parse returns {type: "Buffer", data: Buffer} for Buffers //https://nodejs.org/api/buffer.html#buffer_buf_tojson if (_.isObject(decipheredVal) && decipheredVal.type === "Buffer") { this.setFieldValue(doc, field, decipheredVal.data); } else { this.setFieldValue(doc, field, decipheredVal); } }); doc._ct = undefined; doc._ac = undefined; } } 

在这些函数之后,我把我想要的对象完全解密,最后要做的就是把想要的字段投影回客户端 – 用lodash.pick