2012-09-14 7 views
5

Mam aplikację Expressjs działającą na NodeJS 0.8.8, używając MongoDB i języka szablonów Jade, i chciałbym umożliwić użytkownikowi skonfigurowanie wielu opcji prezentacji w całym serwisie, takich jak tytuły stron, logo itp.Jak mogę zapisać konfigurację strony w MongoDB dla aplikacji NodeJS Express?

Jak mogę przechowywać te opcje konfiguracyjne w bazie danych mongoDB, aby móc je odczytać po uruchomieniu aplikacji, manipulować nimi podczas działania aplikacji i wyświetlać je w szablonach jade?

Oto moja ogólna konfiguracja aplikacji:

var app = module.exports = express(); 
global.app = app; 
var DB = require('./accessDB'); 
var conn = 'mongodb://localhost/dbname'; 
var db; 

// App Config 
app.configure(function(){ 
    ... 
}); 

db = new DB.startup(conn); 

//env specific config 
app.configure('development', function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); // etc 

// use date manipulation tool moment 
app.locals.moment = moment; 

// Load the router 
require('./routes')(app); 

do tej pory stworzyliśmy model o nazwie „Witryna” do kolekcji „siteConfig” i mam funkcję o nazwie getSiteConfig w accessDB.js który działa Site.find() ... aby pobrać pola z jednego dokumentu w kolekcji.

To jest sedno pytania: w jaki sposób należy wprowadzić te pola do aplikacji ekspresowej, aby można było z nich korzystać w całej witrynie? Czy powinienem stosować ten sam wzorzec, którego używałem przy użyciu narzędzia moment.js? W ten sposób:

db.getSiteConfig(function(err, siteConfig){ 
    if (err) {throw err;} 
    app.locals.siteConfig = siteConfig; 
}); 

Jeśli nie, jaki byłby właściwy sposób, aby to zrobić?

Dzięki!

+0

jest to coś chcesz przechowywać w sesji? – c0deNinja

+0

Nie, nie wierzę w to. Nie chcę, aby klient miał do niego dostęp. Po prostu chcę, aby aplikacja ekspresowa po stronie serwera (zwłaszcza Jade) miała do niej dostęp. Mam to działa aż do punktu console.log. Sądzę, że powinienem po prostu spróbować dodać to do app.locals i zobaczyć, co się dzieje, ale nie jestem pewien co do implikacji związanych z bezpieczeństwem korzystania z tego. (lub jego stabilność) – tutley

Odpowiedz

16

Należy rozważyć użycie ekspresowego oprogramowania pośredniego do wczytywania konfiguracji strony.

app.configure(function() { 
    app.use(function(req, res, next) { 
    // feel free to use req to store any user-specific data 
    return db.getSiteConfig(req.user, function(err, siteConfig) { 
     if (err) return next(err); 
     res.local('siteConfig', siteConfig); 
     return next(); 
    }); 
    }); 
    ... 
}); 

Rzucanie błędem to naprawdę zły pomysł, ponieważ spowoduje awarię aplikacji. Używaj zamiast tego next(err);. Przekaże Twój błąd, aby wyrazić errorHandler.

Jeśli już uwierzytelniono użytkownika (na przykład w poprzednim oprogramowaniu pośredniczącym) i zapisano jego dane do req.user, można go użyć, aby uzyskać odpowiednią konfigurację z bazy danych.

Należy jednak zachować ostrożność podczas korzystania z funkcji getSiteConfig w oprogramowaniu pośredniczącym ekspresowym, ponieważ wstrzyma ona ekspresję od dalszego przetwarzania żądania do momentu otrzymania danych.

Należy rozważyć buforowanie siteConfig w sesji ekspresowej, aby przyspieszyć działanie aplikacji. Przechowywanie danych specyficznych dla sesji w sesji ekspresowej jest całkowicie bezpieczne, ponieważ nie ma sposobu, aby użytkownik uzyskał do nich dostęp.

Poniższy kod demonstruje pomysł buforowania siteConfig w wyraźnej sessionn:

app.configure(function() { 
    app.use(express.session({ 
    secret: "your sercret" 
    })); 
    app.use(/* Some middleware that handles authentication */); 
    app.use(function(req, res, next) { 
    if (req.session.siteConfig) { 
     res.local('siteConfig', req.session.siteConfig); 
     return next(); 
    } 
    return db.getSiteConfig(req.user, function(err, siteConfig) { 
     if (err) return next(err); 
     req.session.siteConfig = siteConfig; 
     res.local('siteConfig', siteConfig); 
     return next(); 
    }); 
    }); 
    ... 
}); 
+1

To jest świetna odpowiedź i naprawdę ją doceniam. Niestety nie mogę głosować, ponieważ nie mam wystarczającej reputacji, ale jeśli ktoś to ogląda, zagłosuj na to. Dzięki jeszcze raz. – tutley

Powiązane problemy