简体   繁体   English

如何为 express.js 应用创建超级管理员帐户?

[英]How do I create a superadmin account for an express.js app?

I want to make sure every time an express.js app starts, there is a query made to the mongodb instance user collection to insure that the superadmin account exists.我想确保每次 express.js 应用程序启动时,都会对 mongodb 实例用户集合进行查询,以确保超级管理员帐户存在。 However, everything in the setup phase of an express.js app is synchronous.但是,express.js 应用程序设置阶段的所有内容都是同步的。

Some ideas I have are:我的一些想法是:

  1. Have a system that registers modules.有一个注册模块的系统。 Each module can be loaded with require and has an init method which can be called using the async module's each method which is passed a callback.每个模块都可以用 require 加载,并且有一个init方法,可以使用async模块的each方法调用它,该方法传递一个回调。 Once all the init methods on the module have finished executing the callback function will then run app.listen(process.env.PORT) .一旦模块上的所有 init 方法都执行完回调函数,就会运行app.listen(process.env.PORT)

  2. Write an installation script that is outside the express.js app that is executed at the command line.编写在命令行执行的 express.js 应用程序之外的安装脚本。 This script connects to the mongodb database with mongoose, makes a few queries, and terminates.此脚本使用 mongoose 连接到 mongodb 数据库,进行一些查询,然后终止。 It can be added to the heroku.sh file to insure that it run every time the express.js app is started.可以将它添加到 heroku.sh 文件以确保它在每次 express.js 应用程序启动时运行。

  3. Use waitfor to run the database queries synchronously during the express.js setup phase?在 express.js 设置阶段使用waitfor同步运行数据库查询? This will keep the idea and code clean and simple but it seems like overkill using Fibers for just this one task.这将使想法和代码保持干净和简单,但仅使用 Fibers 来完成这项任务似乎有点过分。

You don't need to perform the database lookup synchronously.您不需要同步执行数据库查找。 Just start your express server in the callback from your database request once you've verified that the user exists.一旦您确认用户存在,只需在您的数据库请求的回调中启动您的快速服务器。 Here's a pseudo-example:这是一个伪示例:

mongoclient.open(function (err, mongoclient) {
    if (err) throw err;  // or otherwise handle it

    var db = client.db("dbname");
    var findAdminUserJSON = {
        // whatever your lookup criteria
    };
    db.collection("user").findOne(findAdminUserJSON, function(err, adminUserData){
        if (err) throw err;  // or otherwise handle it

        if(adminUserData){
            // start express server
        } else {
            // however you want to handle the case of no admin user
        }
    });
});

I just isolated an init function into a separate file.我只是将一个 init 函数隔离到一个单独的文件中。 It only checks the database for the admin user here but in the future, I can register modules which are passed the app and db objects and I'll use async.each to asynchronously load modules and run the init method on each to start off the system.它只在这里检查管理员用户的数据库,但在未来,我可以注册通过appdb对象传递的模块,我将使用async.each异步加载模块并在每个模块上运行init方法以开始系统。 Once that they are all registered run init on the express server.一旦它们全部注册,在快速服务器上运行init

server.js:服务器.js:

'use strict';
// Set the 'NODE_ENV' variable
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
process.env.PORT = process.env.PORT || 3000;

// Apparently __dirname doesn't work on Heroku
// @link http://stackoverflow.com/questions/17212624/deploy-nodejs-on-heroku-fails-serving-static-files-located-in-subfolders
process.env.PWD = process.cwd();

// Load the module dependencies
var mongoose = require('./server/config/mongoose'),
    express = require('./server/config/express'),
    init = require('./server/config/init');

// Create a new Mongoose connection instance
var db = mongoose();

// Create a new Express application instance
var app = express(db);

// Run the init this way in future refactor modules into separate folders.
init(app, db)
    .then(function initialized() {

        // Use the Express application instance to listen to the '3000' port
        app.listen(process.env.PORT);

        // Log the server status to the console
        console.log('Server running at http://localhost:' + process.env.PORT + '/');
    });

// Use the module.exports property to expose our Express application instance for external ussage
module.exports = app;

server/config/init.js:服务器/配置/init.js:

'use strict';

var config = require('./config');

module.exports = function(app, db) {
    return new Promise(function(resolve) {
        var User = db.model('User');
        User.findOne({ email: config.adminAccountEmail}, function(err, user) {
            if (err) throw err;
            if (!user) {
                var newAdmin = new User({
                    email: config.adminAccountEmail,
                    password: config.adminAccountPassword,
                    roles: ['administrator', 'authenticated', 'anonymous']
                });
                newAdmin.save(function(err) {
                    if (err) throw err;
                    resolve();
                })
            } else {
                resolve();
            }
        })
    })
};

server/config/production.js:服务器/配置/production.js:

'use strict';

/**
 * Set the 'production' environment configuration object
 * @link http://docs.mongolab.com/migrating/
 */

module.exports = {
    db: process.env.MONGODB_URI,
    // set this to build
    // dir: 'build/',
    dir: 'client/',
    fileDir: 'files/',
    sessionSecret: process.env.SESSION_SECRET || 'MEAN',
    adminAccountEmail: process.env.ADMIN_ACCOUNT_EMAIL || 'admin@simpleyachtjobs.com',
    adminAccountPassword: process.env.ADMIN_ACCOUNT_PASSWORD || 'password'
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM