हैंडलबार: एक्सेस को "से" संपत्ति को हल करने से इनकार कर दिया गया है क्योंकि यह अपने माता-पिता की "खुद की संपत्ति" नहीं है


15

मैं सर्वर साइड प्रतिपादन के साथ एक Nodejs बैकएंड का उपयोग कर रहा हूँ हैंडलबार का उपयोग कर। docहैंडलबार्स से वस्तुओं की एक सरणी को पढ़ने के बाद , जिसमें कुंजी "सामग्री" और "से" है। हालाँकि जब मैं #eachऑब्जेक्ट्स की सरणी के माध्यम से लूप का उपयोग करने की कोशिश करता हूं , तो त्रुटि "हैंडलबार्स: एक्सेस" से "संपत्ति" को हल करने से इनकार कर दिया गया है क्योंकि यह "अपने माता-पिता की" खुद की संपत्ति नहीं है।

मैंने कंसोल.लॉग () डेटा की कोशिश की है जिसे मैंने डॉक्टर सरणी में लिया है और सब कुछ ठीक लगता है।

कुछ परिप्रेक्ष्य के लिए, यह सामान्य प्रश्न है,
मैंने ऑब्जेक्ट डॉक को res.render तर्कों के अंदर एक कुंजी के रूप में जोड़ा है।

Confession.find()
  .sort({date: -1})
  .then(function(doc){
    for(var i=0; i < doc.length; i++){
      //Check whether sender is anonymous
      if (doc[i].from === "" || doc[i].from == null){
        doc[i].from = "Anonymous";
      }

      //Add an extra JSON Field for formatted date
      doc[i].formattedDate = formatTime(doc[i].date);
    }
    res.render('index', {title: 'Confession Box', success:req.session.success, errors: req.session.errors, confession: doc});
    req.session.errors = null;
    req.session.success = null;
  });

यह .hbs फ़ाइल का वह हिस्सा है जिसके माध्यम से मैं कोशिश कर रहा हूँ:

 {{#each confession}}
    <div class="uk-card uk-card-default uk-card-body uk-margin uk-align-center uk-width-1-2@m" >
        <div class="uk-text-bold">Message: </div>
        <div>{{this.content}}</div>
        <div>From: {{this.from}}</div>
        <div>Posted: {{this.formattedDate}}</div>
    </div>
    {{/each}}

जवाबों:


25

मैं इस मुद्दे को handlebars के लिए एक देव निर्भरता स्थापित करके हल

npm i -D handlebars@4.5.0


वाह यह काम किया, हालांकि यह क्यों हो रहा है? मैं वर्तमान में एक्सप्रेस-हैंडलबार (3.1.0) का उपयोग कर रहा हूं, जिसे मैंने अपने एक्सप्रेस ऐप में एक रेंडर इंजन के रूप में सेट किया है।
ली बून कोंग

मुझे संदेह है कि यह कुछ प्रतिबंधों के कारण हैंडलबार्स के नए संस्करण पर हो रहा था, लेकिन मुझे नहीं पता कि इन प्रतिबंधों पर कैसे काम किया जाए।
ली बून कोंग

खैर, मुद्दा एक्सप्रेस प्लगइन के बीच रहता है जो हैंडलबार्स का समर्थन करता है, लेकिन एक बार हैंडलबार 4.5.0 आपके फ्रंटेंड के मुख्य इंजन के रूप में उपयोग करने के लिए सहेजा जाता है, कृपया मुझे इस पर टिप्पणी करके बताएं।
मेसन

ये काम नहीं कर रहा है। Npm i -D handlebars@4.5.0 पर अमल करने के बाद भी मुझे यही मुद्दा मिलता है
दीपक ठाकुर

सही उत्तर यहाँ है github.com/wycats/handlebars.js/issues/1642
दीपक ठाकुर

12

अगर मानसून का उपयोग करते हैं, तो इस समस्या को हल किया जा सकता है। (एक मानसून के बजाय) एक जोंस ऑब्जेक्ट प्राप्त करने के लिए ()।

dbName.find({}).lean()
  // execute query
  .exec(function(error, body) {
     //Some code
  });

3
भगवान आपका भला करे! जीवन बचाओ!
निक तेइक

1
कोई बात नहीं, खुशी है कि यह मदद की !!
बिलेह

2
काश मैं इस उत्तर को एक से अधिक बार बढ़ा पाता .. हाहा थैंक यू सो मच!
अब्दुस

7

आज मेरे पास हैंडलबार से एक ही चेतावनी है और दृश्य खाली है। नीचे बताया गया है कि मैंने कैसे तय किया:

//  * USERS PAGE
// @description        users route
// @returns           ../views/users.hbs
router.get('/users', async (req, res) => {
  // get all items from db collection
  const collection = 'User'
  await dbFindAllDocs(collection) // <=> wrapper for Model.find() ...
    .then(documents => {
      // create context Object with 'usersDocuments' key
      const context = {
        usersDocuments: documents.map(document => {
          return {
            name: document.name,
            location: document.location
          }
        })
      }
      // rendering usersDocuments from context Object
      res.render('users', {
        usersDocuments: context.usersDocuments
      })
    })
    .catch(error => res.status(500).send(error))
})

users.hbs फ़ाइल

<ul>
{{#each usersDocuments}}
<li>name: {{this.name}} location: {{this.location}}</li>
{{/each}}    
</ul>

contextअपने गुणों से नामित एक पूरी नई वस्तु का निर्माण करना, फिर रेंडर फ़ंक्शन में इसे पास करना समस्या को ठीक करेगा ...

ध्यान दें:

जब हम एक नई वस्तु नहीं बनाते हैं, तो गलती से गोपनीय जानकारी, या जानकारी जो कि प्रोजेट की सुरक्षा से समझौता कर सकती है, को नष्ट करना आसान है, डेटाबेस से लौटाए गए डेटा को मैप करना और केवल दृश्य में जो आवश्यक है उसे पारित करना एक अच्छा अभ्यास हो सकता है। ...


आपके उत्तर के लिए बहूत बहूत धन्यवाद! डेटा के अवांछित एक्सपोज़र को रोकने के लिए एक नई वस्तु बनाना बेहतर लगता है।
ली बून कांग

इस काम के लिए धन्यवाद।
GNETO डोमिनिका

क्या यह तैयार सूची से नई सूची तैयार करके प्रस्तुत करने के लिए 2x समय का उपभोग नहीं करता है?
मुस्तफिजुसा

6

"वाह यह काम किया, हालांकि यह क्यों हो रहा है? मैं वर्तमान में एक्सप्रेस-हैंडलबार (3.1.0) का उपयोग कर रहा हूं जिसे मैंने अपने एक्सप्रेस ऐप में एक रेंडर इंजन के रूप में सेट किया है।" - ली बून कोंग 12 जनवरी को 14:13 बजे

"अतीत में, हैंडलबार आपको टेम्प्लेट से इनपुट ऑब्जेक्ट के प्रोटोटाइप तरीकों और गुणों तक पहुंचने की अनुमति देगा ... इस सुरक्षा से कई सुरक्षा मुद्दे आए हैं ... हैंडलबार्स @^4.6.0 में ऑब्जेक्ट प्रोटोटाइप तक पहुंच है। पूरी तरह से अक्षम कर दिया गया है। अब, यदि आप हैंडलबार्स के इनपुट के रूप में कस्टम कक्षाओं का उपयोग करते हैं, तो आपका कोड अब काम नहीं करेगा ... यह पैकेज स्वचालित रूप से प्रत्येक टेम्पलेट-कॉल में रनटाइम विकल्प जोड़ता है, सुरक्षा प्रतिबंधों को अक्षम करता है ... यदि आपके उपयोगकर्ता लिख ​​रहे हैं। टेम्पलेट्स और आप उन्हें अपने सर्वर पर निष्पादित करते हैं, आपको इस पैकेज का उपयोग नहीं करना चाहिए, बल्कि समस्या को हल करने के अन्य तरीके खोजने चाहिए ...मेरा सुझाव है कि आप अपने वर्ग-उदाहरणों को टेम्प्लेट फ़ंक्शन में पास करने से पहले सादे जावास्क्रिप्ट ऑब्जेक्ट में परिवर्तित करें। आपके द्वारा उपयोग की जाने वाली प्रत्येक संपत्ति या फ़ंक्शन, उसके माता-पिता की "स्वयं की संपत्ति" होनी चाहिए। "- README

अधिक विवरण यहां: https://www.npmjs.com/package/@handlebars/allow-prototyp-access

क्विक एंड ड्यूरी इंस्क्योर मैथोड

उपयोग ( express-handlebarsऔर mongoose):

express-handlebarsआपको टेम्पलेट फ़ंक्शन को पास करने के लिए रनटाइम-विकल्प निर्दिष्ट करने की अनुमति नहीं देता है। यह पैकेज आपके मॉडलों के लिए प्रोटोटाइप चेक को अक्षम करने में आपकी मदद कर सकता है।

"केवल यह करें, यदि आपके पास सर्वर में निष्पादित होने वाले टेम्पलेट्स पर पूर्ण नियंत्रण है।"

कदम:

1 - निर्भरता स्थापित करें

npm i @handlebars/allow-prototype-access

2 - इस स्निपेट को अपने एक्सप्रेस सर्वर को फिर से लिखने के लिए एक उदाहरण के रूप में उपयोग करें

const express = require('express');
const mongoose = require('mongoose');
const Handlebars = require('handlebars');
const exphbs = require('express-handlebars');

// Import function exported by newly installed node modules.
const { allowInsecurePrototypeAccess } = require('@handlebars/allow-prototype->access');

const PORT = process.env.PORT || 3000;

const app = express();

const routes = require('./routes');

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static('public'));

// When connecting Handlebars to the Express app...
app.engine('handlebars', exphbs({
    defaultLayout: 'main',
    // ...implement newly added insecure prototype access
    handlebars: allowInsecurePrototypeAccess(Handlebars)
    })
);
app.set('view engine', 'handlebars');

app.use(routes);

const MONGODB_URI = process.env.MONGODB_URI || >'mongodb://localhost/dbName';

mongoose.connect(MONGODB_URI);

app.listen(PORT, function () {
  console.log('Listening on port: ' + PORT);
});

3 - सर्वर चलाएं और अपने खुश नृत्य करें।


लंबे समय से अधिक सुरक्षित विधि

अपने AJAX कॉल द्वारा लौटे ऑब्जेक्ट को हैंडलबार्स टेम्प्लेट में पास करने से पहले, उसे अपनी .hbsफ़ाइल में पहुंचने वाली प्रत्येक संपत्ति या फ़ंक्शन के साथ एक नई ऑब्जेक्ट में मैप करें । नीचे आप हैंडलबार्स टेम्प्लेट को पास करने से पहले बनाई गई नई वस्तु को देख सकते हैं।

const router = require("express").Router();
const db = require("../../models");

router.get("/", function (req, res) {
    db.Article.find({ saved: false })
        .sort({ date: -1 })
        .then(oldArticleObject => {
            const newArticleObject = {
                articles: oldArticleObject.map(data => {
                    return {
                        headline: data.headline,
                        summary: data.summary,
                        url: data.url,
                        date: data.date,
                        saved: data.saved
                    }
                })
            }
            res.render("home", {
                articles: newArticleObject.articles
            })
        })
        .catch(error => res.status(500).send(error));
});

आपकी मोंगोज़ क्वेरी

अगर मैं गलत हूं तो मुझे सुधार लो लेकिन मुझे लगता है कि यह आपकी क्वेरी के लिए काम कर सकता है ...

Confession.find()
    .sort({ date: -1 })
    .then(function (oldDoc) {

        for (var i = 0; i < oldDoc.length; i++) {
            //Check whether sender is anonymous
            if (oldDoc[i].from === "" || oldDoc[i].from == null) {
                oldDoc[i].from = "Anonymous";
            }

            //Add an extra JSON Field for formatted date
            oldDoc[i].formattedDate = formatTime(oldDoc[i].date);
        }

        const newDoc = {
            doc: oldDoc.map(function (data) {
                return {
                    from: data.from,
                    formattedDate: data.formattedDate
                }
            })
        }

        res.render('index', { title: 'Confession Box', success: req.session.success, errors: req.session.errors, confession: newDoc.doc });
        req.session.errors = null;
        req.session.success = null;
    });

5

npm हैंडलबार्स संस्करण 4.5.3 स्थापित करने का प्रयास करें

npm हैंडलबार@4.5.3 स्थापित करें

इसने मेरे लिए काम किया


यह एक टिप्पणी होनी चाहिए
अरुण विनोथ

मैं वर्तमान में एक्सप्रेस-हैंडलबार का उपयोग कर रहा था, संस्करण 3.1.0
ली बून कांग

धन्यवाद, मैंने आपके और @ मेसन के दोनों काम करने की कोशिश की है, लेकिन मुझे यकीन नहीं है कि ऐसा क्यों हो रहा है।
ली बून कोंग

3

संस्करण 4.6.0 से शुरू होकर, हैंडलबार्स प्रोटोटाइप गुणों और डिफ़ॉल्ट रूप से संदर्भ ऑब्जेक्ट के तरीकों तक पहुंचने से मना करते हैं। यह यहां वर्णित एक सुरक्षा मुद्दे से संबंधित है: https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html

Https://github.com/wycats/handlebars.js/issues/1642 का संदर्भ लें

यदि आप निश्चित हैं कि केवल डेवलपर्स के पास टेम्प्लेट्स की पहुंच है, तो निम्नलिखित पैकेज को स्थापित करके प्रोटोटाइप एक्सेस की अनुमति देना संभव है:

npm i @handlebars/allow-prototype-access

यदि आप एक्सप्रेस-हैंडलबार का उपयोग कर रहे हैं, तो आपको निम्न कार्य करना चाहिए:

const 
    express = require('express'),
    _handlebars = require('handlebars'),
    expressHandlebars = require('express-handlebars'),
    {allowInsecurePrototypeAccess} = require('@handlebars/allow-prototype-access')

const app = express()

app.engine('handlebars', expressHandlebars({
    handlebars: allowInsecurePrototypeAccess(_handlebars)
}))
app.set('view engine', 'handlebars')

धन्यवाद यह काम किया। इसलिए हमें हर बार यह करना होगा जब हमें एक्सप्रेस-हैंडलबार का उपयोग करना होगा?
यश बूरा

2

हैंडलबार्स की हालिया रिलीज़ में एक परिवर्तन हुआ जिससे यह त्रुटि हुई है।

आप केवल उनके प्रलेखन में उनके द्वारा सुझाए गए कॉन्फ़िगरेशन को जोड़ सकते हैं, हालांकि, जागरूक रहें, आपके कार्यान्वयन के आधार पर, यह XXS और RCE हमलों के लिए भेद्यता का कारण बन सकता है।

https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access

Confession.find()
  .sort({date: -1})
  .then(function(doc){
    for(var i=0; i < doc.length; i++){
      //Check whether sender is anonymous
      if (doc[i].from === "" || doc[i].from == null){
        doc[i].from = "Anonymous";
      }

      //Add an extra JSON Field for formatted date
      doc[i].formattedDate = formatTime(doc[i].date);
    }
    res.render('index', {title: 'Confession Box', success:req.session.success, errors: req.session.errors, confession: doc}, {

      // Options to allow access to the properties and methods which as causing the error.

      allowProtoMethodsByDefault: true,
      allowProtoPropertiesByDefault: true

    });

    req.session.errors = null;
    req.session.success = null;
  });

आह, इसलिए कि मैं विकल्प जोड़ता हूं, बहुत बहुत धन्यवाद!
ली बून कोंग

1
यह मेरे लिए काम नहीं किया। एक कॉलबैक की उम्मीद की गई थी, एक विकल्प वस्तु नहीं।
mrg95

0

द्वारा लौटाए गए डेटा से एक और नई वस्तु या एरियर बनाना find() समस्या को हल करेगा। एक साधारण चित्रण के नीचे देखें

app.get("/",(req,res)=>{

 let com = require('./MODELCOM')    // loading model
 let source=fs.readFileSync(__dirname+"/views/template.hbs","utf-8");

 com.find((err,data)=>{
    // creation new array  using map
   let wanted = data.map(doc=>{
       return {
           name:doc.name,
           _id:doc._id
        }
   })

    let html= handlebar.compile(source);
  fs.writeFileSync(__dirname+"/views/reciever.html",html({communities:wanted}))
    res.sendFile(__dirname+"/views/reciever.html")
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.