{"id":207930,"date":"2013-12-31T15:27:03","date_gmt":"2013-12-31T11:27:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=207930"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=207930","title":{"rendered":"<span class=\"post_title\">\u0411\u0430\u0437\u043e\u0432\u043e\u0435 Node.JS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c express<\/span>"},"content":{"rendered":"<div class=\"content html_format\"> \t\t\t\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.<br \/>  \u0418\u0441\u043a\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u044e, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u043e\u0435 Node.JS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c express, \u0442\u043e\u0447\u043d\u0435\u0435 \u043a\u0430\u043a\u0430\u044f \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u043e \u0442\u0430\u043a \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0433\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b.<br \/>  \u041f\u043e\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e, \u0434\u0430\u0431\u044b \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043a\u0430\u043a \u0438 \u044f \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c.<\/p>\n<p>  \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c. \u041e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e. \u041c\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043a\u043e\u0434\u0430.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c, \u0445\u043e\u0447\u0443 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043c\u043e\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f. \u042f, \u0431\u044b\u0442\u044c \u043c\u043e\u0436\u0435\u0442, \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0443\u0447\u0442\u0443, \u0438\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u0430\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u0443\u044e \u043d\u0430 \u0447\u0435\u043c-\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0431\u0443\u0434\u0443 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0435\u043d \u0437\u0430 \u043f\u043e\u043f\u0440\u0430\u0432\u043a\u0438 \u0438 \u0443\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u044f \u043f\u043e \u0441\u0442\u0430\u0442\u044c\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0443.<\/p>\n<p>  \u0417\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439: \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043c\u043e\u0433\u043b\u043e \u0431\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043b\u0438\u0431\u043e \u0436\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b.<\/p>\n<p>  \u0418\u0442\u0430\u043a. \u041d\u0430\u0447\u043d\u0435\u043c, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<pre><code>express - \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442, \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f http-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 mongoose - \u0444\u0440\u0435\u0439\u043c\u0432\u0435\u0440\u043a, \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 MongoDB mongodb - native-driver \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 MongoDB \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e connect-mongo - \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b express \u0441 session node-uuid - \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432) async - \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0446\u0435\u043f\u043e\u0447\u043a\u043e\u0439 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0430\u043a\u0430 Promise ejs-locals - \u0434\u0432\u0438\u0436\u043e\u043a \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 nconf - \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 config.json) string - \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438, \u0442\u0430\u043a\u0436\u0435 \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u0441\u0442\u0440\u043e\u043a \u043e\u0442 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0445 \u0432\u0435\u0449\u0435\u0439, \u0442\u0438\u043f\u0430 html \u0442\u0435\u0433\u043e\u0432 \u0438 \u0442\u0434 validator - \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 winston - \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0433\u043e \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043e\u043a <\/code><\/pre>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<br \/>  npm install &lt;&lt;module_name&gt;&gt; &#8212;save<\/p>\n<p>  <b>&#8212;save<\/b> \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u0432 dependency (package.json), \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445.<\/p>\n<p>  \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439:<\/p>\n<pre><code>\t\/config \t\tconfig.json \t\tindex.js \t\/middleware \t\tcheckAuth.js \t\terrorHandler.js \t\tindex.js \t\/models \t\tuser.js \t\/public \t\t\/*JS, CSS, HTML static files*\/ \t\/routes \t\tauthentication.js \t\terror.js \t\tindex.js \t\tmain.js \t\tregister.js \t\/utils \t\tindex.js \t\tlog.js \t\tmongoose.js \t\tvalidate.js \t\/views \t\tindex.ejs \tmanage.js \tpackage.json \tserver.js <\/code><\/pre>\n<p>  \u0421\u0435\u0439\u0447\u0430\u0441, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043e\u0431\u044a\u044f\u0441\u043d\u044e \u0432 \u0447\u0435\u043c \u0441\u043e\u043b\u044c \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 \u0438 \u0435\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432.<br \/>  \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u0441\u0435 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<h3>server.js<\/h3>\n<p>  <\/p>\n<pre><code class=\"javascript\">var express = require('express'),     middleware = require('.\/middleware'),     http = require('http'),     app = express(),     config = require('.\/config'),     log = require('.\/utils\/log')(app, module);  middleware.registerMiddleware(app, express);  http.createServer(app).listen(config.get('port'), function(){     log.info('Express server listening on port ' + config.get('port')); }); <\/code><\/pre>\n<p>  \u0412 <b>server.js<\/b> \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 epxress <b>app<\/b>, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c <b>middleware<\/b>, \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <b>registerMiddleware<\/b> \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 middleware \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<br \/>  \u0414\u0430\u043b\u044c\u0448\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0440\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043a\u0430\u0437\u0430\u043d \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435.<\/p>\n<h3>package.json<\/h3>\n<p>  <\/p>\n<pre><code>{   &quot;name&quot;: &quot;test_express_app&quot;,   &quot;version&quot;: &quot;0.0.1&quot;,   &quot;private&quot;: true,   &quot;scripts&quot;: {     &quot;start&quot;: &quot;node server.js&quot;   },   &quot;dependencies&quot;: {     &quot;express&quot;: &quot;~3.4.6&quot;,     &quot;mongoose&quot;: &quot;~3.8.1&quot;,     &quot;node-uuid&quot;: &quot;~1.4.1&quot;,     &quot;nconf&quot;: &quot;~0.6.9&quot;,     &quot;winston&quot;: &quot;~0.7.2&quot;,     &quot;async&quot;: &quot;~0.2.9&quot;,     &quot;mongodb&quot;: &quot;~1.3.22&quot;,     &quot;ejs-locals&quot;: &quot;~1.0.2&quot;,     &quot;connect-mongo&quot;: &quot;~0.4.0&quot;,     &quot;validator&quot;: &quot;~2.0.0&quot;,     &quot;string&quot;: &quot;~1.7.0&quot;   } }  <\/code><\/pre>\n<p>  \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0432\u0441\u044e \u043d\u0443\u0436\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b.<\/p>\n<h3>manage.js<\/h3>\n<p>  <\/p>\n<pre><code class=\"javascript\">var mongoose = require('.\/utils\/mongoose'),     async = require('async'),     User = require('.\/models\/user'),     log = require('.\/utils\/log')(null, module),     config = require('.\/config');  function openConnection(cb) {     mongoose.connection.on('open', function () {         log.info('connected to database ' + config.get('db:name'));         cb();     }); }  function dropDatabase(cb) {     var db = mongoose.connection.db;     db.dropDatabase(function () {         log.info('dropped database ' + config.get('db:name'));         cb();     }); }  function createBaseUser(cb) {     var admin = new User({         username: 'admin',         password: config.get('project:admin:password'),         email: config.get('project:admin:email'),         role: 1     });     admin.save(function () {         log.info('created database ' + config.get('db:name'));         log.info('created base admin user');         cb();     }); }  function ensureIndexes(cb) {     async.each(Object.keys(mongoose.models), function (model, callback) {         mongoose.models[model].ensureIndexes(callback);     }, function () {         log.info('indexes ensured completely');         cb();     }); }  function closeConnection() {     mongoose.disconnect();     log.info('disconnected'); }  async.series(     [         openConnection,         dropDatabase,          createBaseUser,          ensureIndexes     ],     closeConnection ); <\/code><\/pre>\n<p>  \u041d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 default \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<h3>config<\/h3>\n<p>  <\/p>\n<h4>config.json<\/h4>\n<p>  <\/p>\n<pre><code>{ \t&quot;port&quot;: 3000,     &quot;db&quot;: {         &quot;connection&quot;: &quot;mongodb:\/\/localhost&quot;,         &quot;name&quot;: &quot;db_name&quot;,         &quot;options&quot;: {             &quot;server&quot;: {                 &quot;socketOptions&quot;: {                     &quot;keepAlive&quot;: 1                 }             }         }     },     &quot;session&quot;: {         &quot;secret&quot;: &quot;secret_key&quot;,         &quot;key&quot;: &quot;cid&quot;,         &quot;cookie&quot;: {             &quot;path&quot;: &quot;\/&quot;,             &quot;httpOnly&quot;: true,             &quot;maxAge&quot;: null         }     } } <\/code><\/pre>\n<h4>index.js<\/h4>\n<p>  <\/p>\n<pre><code class=\"javascript\">var nconf = require('nconf'); var path = require('path');  nconf.argv()     .env()     .file({file: path.join(__dirname, 'config.json')});  module.exports = nconf; <\/code><\/pre>\n<p>  \u0412 \u0444\u0430\u0439\u043b\u0435 <b>config.js<\/b> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0435\u0441\u0441\u0438\u0438.<br \/>  \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 <b>config<\/b> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0430\u043a\u0435\u0442 <b>nconf<\/b>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 getter \u0438 setter \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0447\u0435\u0440\u0435\u0437 \u0441\u0438\u043c\u0432\u043e\u043b <b>:<\/b>:<\/p>\n<pre><code class=\"javascript\">config.get('session:secret'); config.get('session:cookie:path'); <\/code><\/pre>\n<h3>middleware<\/h3>\n<p>  <\/p>\n<pre><code class=\"javascript\">exports.registerMiddleware = function (app, express) {     var ejs = require('ejs-locals'),         path = require('path'),         config = require('..\/config'),          mongoose = require('..\/utils\/mongoose'),         MongoStore = require('connect-mongo')(express),          router = require('..\/routes'),         errorHandler = require('.\/errorHandler')(app, express),          checkAuth = require('.\/checkAuth');      \/**      * Page Rendering      * *\/     app.engine('html', ejs);     app.engine('ejs', ejs);     app.set('views', path.join(__dirname, '..\/views'));     app.set('view engine', 'ejs');       \/**      * Public directory      * *\/     app.use(express.static(path.join(__dirname, '..\/public')));     app.use(&quot;\/public&quot;, express.static(path.join(__dirname, '..\/public')));       \/**      * Favicon      * *\/     app.use(express.favicon('public\/images\/favicon.ico'));       \/**      * Logger      * *\/     if (app.get('env') == 'development') {         app.use(express.logger('dev'));     }       \/**      * Session      * *\/     app.use(express.bodyParser());     app.use(express.cookieParser());     app.use(express.session({         secret: config.get('session:secret'),         key: config.get('session:key'),         cookie: config.get('session:cookie'),         store: new MongoStore({mongoose_connection: mongoose.connection})     }));      \/**      * Authorization Access      * *\/     app.use(checkAuth);       \/**      * Routing      * *\/     app.use(app.router);     router(app);       \/**      * Error handing      * *\/     app.use(errorHandler); }; <\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432\u0441\u0435 <b>middleware<\/b> \u043d\u0435 \u0437\u0430\u0441\u043e\u0440\u044f\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0431\u044b\u0442\u044c \u043c\u043e\u0436\u0435\u0442, \u0435\u0435 \u043f\u0440\u0438\u0439\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c, \u043f\u043e \u0445\u043e\u0434\u0443 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  \u0425\u043e\u0447\u0443 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u2014 <b>errorHandler<\/b> middleware \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e handling \u043e\u0448\u0438\u0431\u043e\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0448\u0438\u0431\u043a\u0438<\/p>\n<h4>errorHandler<\/h4>\n<p>  <\/p>\n<pre><code class=\"javascript\">var config = require('..\/config');  var sendHttpError = function (error, res) {     res.status(error.status);      if (res.req.headers['x-requested-width'] === 'XMLHttpRequest') {         res.json(error);     } else {         res.render('error', {             error: {                 status: error.status,                 message: error.message,                 stack: config.get('debug') ? error.stack : ''             },             project: config.get('project')         });     } };  module.exports = function (app, express) {     var log = require('..\/utils\/log')(app, module),         HttpError = require('..\/error').HttpError;      return function(err, req, res, next) {         if (typeof err === 'number') {             err = new HttpError(err);         }         if (err instanceof HttpError) {             sendHttpError(err, res);         } else {             if (app.get('env') === 'development') {                 express.errorHandler()(err, req, res, next);             } else {                 log.error(err);                 err = new HttpError(500);                 sendHttpError(err, res);             }         }     }; }; <\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c middleware <b>checkAuth<\/b>  <\/p>\n<pre><code class=\"javascript\">var HttpError = require('..\/error').HttpError;  module.exports =  function (req, res, next) {     if (!req.session.user) {         return next(new HttpError(401, &quot;You are not authorized!&quot;));     }     next(); }; <\/code><\/pre>\n<p>  \u041a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0435\u0441\u0441\u0438\u0438 \u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f, \u0431\u0443\u0434\u0435\u0442 \u0431\u0440\u043e\u0441\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443. \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 middleware \u0438\u043b\u0438 \u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043c\u0435\u0442\u043e\u0434, \u0433\u0434\u0435 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f:<\/p>\n<pre><code class=\"javascript\">app.get('\/user-info', checkAuth, function (req, res, next) {     \/\/do your staff }); <\/code><\/pre>\n<h2>models<\/h2>\n<p>  C \u043f\u043e\u043c\u043e\u0449\u044c\u044e Mongoose \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">var crypto = require('crypto'),     mongoose = require('..\/utils\/mongoose'),     Schema = mongoose.Schema,     async = require('async');  var User = new Schema({     username: {         type: String,         unique: true,         required: true     },     hashedPassword: {         type: String,         required: true     },     salt: {         type: String,         required: true     } });  User.methods.encryptPassword = function (password) {     return crypto.createHmac('sha1', this.salt).update(password).digest('hex'); };  User.virtual('password')     .set(function (password) {         this._plainPassword = password;         this.salt = Math.random() + '';         this.hashedPassword = this.encryptPassword(password);     })     .get(function () {         return this._plainPassword;     });  User.methods.checkPassword = function (password) {     return this.encryptPassword(password) === this.hashedPassword; };  module.exports = mongoose.model('User', User);  <\/code><\/pre>\n<h3>public<\/h3>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0438 css \u0444\u0430\u0439\u043b\u044b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0438\u0437\u0432\u043d\u0435. \u041e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u0430\u044f \u043e\u043f\u0446\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">\/**  * Public directory  * *\/ app.use(express.static(path.join(__dirname, '..\/public'))); app.use(&quot;\/public&quot;, express.static(path.join(__dirname, '..\/public'))); <\/code><\/pre>\n<h2>routes<\/h2>\n<p>  C\u0430\u043c\u043e\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0440\u043e\u0443\u0442\u0438\u043d\u0433. \u0444\u0430\u0439\u043b <b>index.js<\/b><\/p>\n<pre><code class=\"javascript\">var main = require('.\/main'),     register = require('.\/register'),     authentication = require('.\/authentication'),     error = require('.\/error');  module.exports = function (app) {     app.get('\/', main.home);      app.post('\/register', register.requestRegistration);      app.get('\/users', authentication.users);     app.get('\/users\/:id', authentication.user);      app.get('*', error['404']); }; <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448\u0438 \u0440\u043e\u0443\u0442\u044b, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u0435\u043d\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044f\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <b>route &quot;\/&quot;<\/b>:  <\/p>\n<pre><code class=\"javascript\">\/**  * Method: GET  * URI: \/  * *\/ exports.home = function(req, res, next) {     res.render('index'); }; <\/code><\/pre>\n<p>  C\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f \u0438 \u0432\u0441\u0435. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u0430\u043a \u0431\u0430\u0437\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0441\u0435\u0441\u0441\u0438\u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 <b>middleware<\/b>. \u0412\u0441\u044e \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0443, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0443\u044e \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0432 <b>models\/user.js<\/b>, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443.<\/p>\n<p>  PS:<br \/>  \u0412 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0438\u0437 \u0441\u043a\u0440\u0438\u043d\u043a\u0430\u0441\u0442\u043e\u0432 \u0418.\u041a\u0430\u043d\u0442\u043e\u0440\u0430. \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 <a href=\"http:\/\/learn.javascript.ru\/nodejs-screencast\">\u0441\u043a\u0440\u0438\u043d\u043a\u0430\u0441\u0442<\/a>.<br \/>  \u0422\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0438\u0437 \u043a\u0443\u0440\u0441\u043e\u0432 \u043f\u043e <a href=\"https:\/\/education.mongodb.com\/\"><b>MongoDB<\/b><\/a> \t\t\t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/207930\/\"> http:\/\/habrahabr.ru\/post\/207930\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\"> \t\t\t\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.<br \/>  \u0418\u0441\u043a\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u044e, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u043e\u0435 Node.JS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c express, \u0442\u043e\u0447\u043d\u0435\u0435 \u043a\u0430\u043a\u0430\u044f \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u043e \u0442\u0430\u043a \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0433\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b.<br \/>  \u041f\u043e\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e, \u0434\u0430\u0431\u044b \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043a\u0430\u043a \u0438 \u044f \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c.<\/p>\n<p>  \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c. \u041e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e. \u041c\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043a\u043e\u0434\u0430.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-207930","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/207930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=207930"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/207930\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=207930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=207930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=207930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}