【问题标题】:Express Handlebars Won't Render DataExpress Handlebars 不会呈现数据
【发布时间】:2020-05-02 07:44:28
【问题描述】:

我正在使用 Express-Handlebars 模板引擎处理 NodeJS 和 Express。

Handlebars 在尝试渲染模板时抛出以下错误:

Handlebars:访问已被拒绝解析属性“用户名” 因为它不是其父级的“自己的财产”。您可以添加一个 禁用检查或此警告的运行时选项:请参阅 https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access 了解详情

根据上面的链接:

从 4.6.0 版本开始,Handlebars 默认禁止访问上下文对象的原型属性和方法。原因是这种可能性引起的各种安全问题。

我的 app.js 包含以下内容:

const exphbs = require('express-handlebars');
const express = require('express');
// Init Express
const app = express();
// VIEW ENGINE
app.engine('handlebars', exphbs({
  defaultLayout: 'main'
}));
app.set('view engine', 'handlebars');

我的路由文件通过 Mongoose 从 MongoDB 获取:

//@GET - View
router.get('/', authMiddleware, (req, res, next) => {
  // Mongoose
  Model.find({ user: req.user._id })
    .sort({ date: -1 })
    .then(model => {
      res.render('/overview', { model: model })
    })
    .catch(err => {
      if (err) throw err;
      req.flash('error_msg', 'No Model Found');
    })

})

模型是一个对象数组

这个问题是在我开始添加车把助手之后才开始发生的。我已经删除了帮助程序并恢复到我原来的配置设置(上图),但无济于事。我试过删除 node_modules 文件夹并重新安装 npm。

发送的是对象数组,我正在尝试使用 {{#each model}} 帮助器循环对象的属性,并通过每个对象中的 {{prop1}} 引用各个属性。

根据 Handlebars 的说法,禁用 proto 属性默认为 false,此更改不应破坏任何内容。

我的问题:

  1. 我是否错误地将数据发送到车把?如果是这样,将数据发送到 express-handlebars 模板进行渲染的正确方法是什么(不让我的服务器暴露于安全漏洞)?

提前谢谢你。

【问题讨论】:

  • 尝试通过这样做从其上下文对象属性中剥离数据; model = model.toJSON();
  • 嗨,Mas,感谢您的建议。 toJSON() 的文档说这是一个日期,所以这不起作用。
  • 正确!我曾经使用 Sequelize,toJSON() 成功了。如果您已经尝试过但没有成功,我认为使用 lean 可以在 Mongoose 中实现相同的结果
  • 精益工作!太棒了,比kyou Mas!

标签: node.js express mongoose server-side-rendering express-handlebars


【解决方案1】:

正确!我曾经与SequelizetoJSON() 一起工作。

如果您已经尝试过但没有成功,我认为在 Mongoose 中使用 lean – mas 2 小时前可以实现相同的结果

我在.sort().then() 之间添加了.lean,这有效!

【讨论】:

    【解决方案2】:

    正如@OctavianLabs 的回答,这对我有帮助:

    const posts = await this.find({})
     .limit(amount)
     .lean();
    

    mongoose 的 lean 方法返回纯 JavaScript 对象 (POJO),而不是 Mongoose 文档。

    【讨论】:

      【解决方案3】:

      @OctavianLabs 对于这种错误。您应该尝试以下代码。

       Model.find({ user: req.user._id })
          .sort({ date: -1 })
          .lean()
          .then(model => {
            res.render('/overview', { model: model })
          })
      

      【讨论】:

        【解决方案4】:

        我在升级车把套件时遇到了同样的问题。为了让您的系统尽快恢复在线,请删除 package.json 中的 handlebars 条目,然后在其位置插入这一行。

        "handlebars": "4.5.3",
        

        从 4.6.0 版开始,Handlebars 默认禁止访问上下文对象的原型属性和方法。这与此处描述的安全问题有关: https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html

        参考 https://github.com/wycats/handlebars.js/issues/1642

        上述 URL 中的一个示例显示了将 Mongoose 响应转换为 JSON:

        app.get('/test', function (_req, res) {
            Kitten.find({}).then(kittens => {
                res.render('test.hbs', {
                    kittens: kittens.map(kitten => kitten.toJSON())
                })
            })
        });
        

        如果您确定只有受信任的开发人员且没有最终用户可以访问车把模板,则可以通过安装以下软件包来允许原型访问:

        npm install @handlebars/allow-prototype-access
        

        这是一个使用示例:

        const express = require('express');
        const Handlebars = require('handlebars')
        const expressHandlebars = require('express-handlebars');
        const {allowInsecurePrototypeAccess} = require('@handlebars/allow-prototype-access')
        
        const app = express();
        
        app.engine('handlebars', expressHandlebars({
            handlebars: allowInsecurePrototypeAccess(Handlebars)
        }));
        app.set('view engine', 'handlebars');
        ...
        

        另一个选择是使用 mongoose .lean() 函数。这样做的好处是比传统的猫鼬查询要快得多。但它也有一些缺点。默认情况下,Mongoose 查询返回 Mongoose Document 类的一个实例。这些对象包含许多用于更改跟踪的内部状态,并具有其他方法,例如 .save()。启用精益选项会告诉 Mongoose 跳过实例化完整的 Mongoose 文档,而只返回纯 javascript 对象。

        【讨论】:

          【解决方案5】:

          .find() 之后使用.lean() 它可以正常工作

          【讨论】:

          • 如果可能,请努力提供额外的解释,而不仅仅是代码。此类答案往往更有用,因为它们可以帮助社区成员(尤其是新开发人员)更好地理解解决方案的推理,并有助于避免需要解决后续问题。
          【解决方案6】:

          在 .find() 之后使用 .lean() 这个函数使数据获取更快

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多