如何存储和检索存储在MongoDB文档中的JavaScript函数?

时间:2018-01-30 06:16:31

标签: javascript mongodb meteor

我有一个“Assignments”MongoDB集合,其中包含一个包含评分函数的文档。我想将此评分函数存储在作业文档中,因为评分逻辑可能随着创建新作业而随时间而变化:

分配

{
  _id: "assignment1",
  question: "Number between 1 and 10",
  scoringFunction: function (value) { value * 2 }
}

当用户完成作业时,会插入“事件”集合中的新文档:

事件

{
  _id: "event1",
  answer: "4",
  score: "8"
}

我可以将上面的Assignment文档插入到我的Assignments集合中,但是当我尝试检索scoringFunction时,它不再是一个函数,它就是一个对象。

一些调试代码:

const assignment = Assignments.findOne({ _id: "test" })
console.log(assignment.scoringFunction)

调试代码输出:

Code {
  _bsontype: 'Code',
  code: 'function (value) { value * 2 }',
  scope: undefined
}

如何将此对象解码回JavaScript函数,可以使用参数调用以计算得分?

1 个答案:

答案 0 :(得分:0)

警告:避免将执行的代码与数据一起存储。

理想情况下 - 从数据安全角度来看 - 不要在您的数据中存储可执行代码。

如果黑客(或用户)能够在您的数据库中更改此功能,他们可能会损害您的数据或在功能无法正常工作时破坏您的应用。

已实施解决方案

我将在作业中存储评分函数的名称。

分配

{
  _id: "assignment1",
  question: "Number between 1 and 10",
  scoringFunction: "scoreAssignment1"
}

Meteor Logic

const scoreAssignment1 = (value) => value * 2
const assignment = Assignments.findOne({ _id: "test"})
console.log(Meteor.call(assignment.scoringFunction, 2))    
// output: 4

危险解决方案

scoringFunction的正文存储在字符串中,然后使用new Function()从所需的参数和函数体字符串创建函数。

分配

{
  _id: "assignment1",
  question: "Number between 1 and 10",
  scoringFunction: "value * 2"
}

事件逻辑

const assignment = Assignments.findOne({ _id: "test"})
const scoringFunction = new Function('value', assignment.scoringFunction)
console.log(scoringFunction(2))
// output: 4