Express Руль не будет отображать данные - PullRequest
4 голосов
/ 15 января 2020

Я работаю с NodeJS и Express, используя Express -Handlebars.

Handlebars выдает следующую ошибку при попытке визуализации шаблона:

Handlebars: доступ запрещен для разрешения свойства «имя пользователя», поскольку оно не является «собственным свойством» его родителя. Вы можете добавить опцию времени выполнения, чтобы отключить проверку или это предупреждение: Подробнее см. https://handlebarsjs.com/api-reference/runtime-options.html#options -to-control-prototype-access

По приведенной выше ссылке:

Начиная с версии 4.6.0, Handlebars по умолчанию запрещает доступ к свойствам и методам прототипа объекта контекста. Причиной являются различные проблемы безопасности, которые возникают из-за этой возможности.

Мое приложение. 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');

Мой файл маршрута выбирается из MongoDB через Mon goose:

//@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.

. Отправляется массив объектов, и я пытаюсь l oop по свойствам объектов, используя {{#each model }} помощник и ссылка на отдельные свойства с помощью {{prop1}} внутри каждого.

Согласно Handlebars, это отключение свойств proto по умолчанию ложно, и это изменение ничего не должно нарушать.

Мой вопрос:

  1. Я неправильно отправляю данные на руль? Если да, то как правильно (не подвергая мой сервер дырам в безопасности) отправлять данные в шаблон express -handlebars для рендеринга?

Заранее спасибо.

Ответы [ 5 ]

4 голосов
/ 15 января 2020

Правильно! Раньше я работал с Sequelize и toJSON() сделали свое дело.

Если вы уже пробовали это, и оно не сработало, я думаю, что тот же результат в Mon goose мог бы быть достигнут при использовании Lean - Mas 2 часа go

Я добавил .lean между .sort() и .then(), это сработало!

3 голосов
/ 18 февраля 2020

У меня была такая же проблема, когда я обновлял пакет руля. Чтобы как можно быстрее восстановить работоспособность вашей системы, удалите запись руля из пакета. json А затем вставьте эту строку на свое место.

"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 показывает Пн goose ответ преобразован в 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');
...

Другой вариант - использовать функцию mon goose .lean (). Преимущество этого в том, что он намного быстрее, чем традиционный запрос mon goose. Но у него есть и минусы. По умолчанию запросы Mon goose возвращают экземпляр класса Mon goose Document. Эти объекты содержат много внутреннего состояния для отслеживания изменений и имеют дополнительные методы, такие как .save (). Включение опции lean говорит Mon goose, что нужно пропустить создание экземпляра полного документа Mon goose и просто вернуть простой объект javascript.

1 голос
/ 09 февраля 2020

@ OctavianLabs для такого рода ошибки. Вы должны попробовать следующий код.

 Model.find({ user: req.user._id })
    .sort({ date: -1 })
    .lean()
    .then(model => {
      res.render('/overview', { model: model })
    })
1 голос
/ 24 января 2020

Как ответил @OctavianLabs, это помогло мне:

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

Метод lean для mon goose возвращает простые JavaScript объекты (POJO), а не Mon goose документы.

0 голосов
/ 06 мая 2020

использовать .lean() после .find() работает нормально

...