[eggjs/egg]应用启动时,如何在egg-mongoose插件启用之前,修改mongo数据库配置并生效?

2024-03-29 148 views
1

请问一下大佬们,我有一个需求这样:在生产环境下,不能直接在config.prod.js中硬编码mongodb数据库的地址、账号、密码等敏感配置信息,如何在应用启动前,将敏感配置信息传入,从而应用到egg-mongoose插件中。 我的实现这样子:在生产环境中新建extend-config.json文件,该文件里面写了敏感配置信息,然后在应用启动前,app.js去读取该配置文件并修改app.config。但是上述方法实现起来出问题了,发现更新后的配置信息没有传入egg-mongoose插件中,egg-mongoose插件就已经启动了,以下是我的代码: ${baseDir}/app.js

class AppBootHook {
  constructor(app) {
    this.app = app;
  }

  configWillLoad() {
    // 此时 config 文件已经被读取并合并,但是还并未生效
    // 这是应用层修改配置的最后时机
    // 注意:此函数只支持同步调用
    const app = this.app;

    let extendConfig = {};
    const configFilePath = path.join(app.config.baseDir, 'config/extend-config.json');
    if (fs.existsSync(configFilePath)) {
      extendConfig = JSON.parse(fs.readFileSync(configFilePath, { encoding: 'utf-8' }));
    }
    Object.assign(app.config, extendConfig);
  }
}
module.exports = AppBootHook;

我这种方式哪里出了问题吗,或者大佬们是怎么做的。

回答

3

忽略我刚刚说的……我们公司的做法是做生产网隔离,普通人无法访问到生产网的数据库,所以也无所谓把密码填在配置里了

6

egg-mongoose 的代码应该不复杂,可以看一下源码,看为什么你动态改的配置不生效

5

嗯嗯,我上一家公司就是这么操作的,不过新东家没有做网络隔离,所以密钥类的配置信息都不能直接暴露明文。我检查了一下run/application_config.json,问题已经解决了,是我的疏忽造成的,漏了一行代码,忽略这个issue吧。 另外补充:这个操作思路是可行的,仓库忽略提交该敏感信息配置文件extend-config.json,在生产环境下,应用启动前再从服务器其他目录读取。

4

你这个做法可能不好做容器化,未来横向扩展可能受限

1

果然还是有问题,虽然run/application_config.json里的配置是最新的,但是实际上mongo连接没有使用到该配置,等我排查清楚后再来

3

正如上面所说:egg-mongoose 的代码应该不复杂,可以看一下源码,看为什么你动态改的配置不生效

3
20E8C008-0273-45BC-9203-D105AA25BD0E

mongoose配置里面还需要配app属性吗,排查app.config.mongoose.app为undefined导致插件没有被执行,当mongoose配置在config/config.default.js的时候app属性自动被设置为true

2

问题已彻底解决,首先给出结论:configWillLoad钩子确实会在插件的启动之前执行,没半点毛病。那我的问题出在哪里呢,还是在配置的处理上,罪魁祸首就是这行代码Object.assign(app.config, extendConfig);, 直接把egg-mongoose的一些默认插件配置给覆盖掉了。 查看egg-mongoose源码,egg-mongoose/config/config.default.js有相应插件的默认配置:

exports.mongoose = {
  url: '',
  options: {},
  plugins: [],
  loadModel: true,
  app: true,
  agent: false,
};

其中app和loadModel两个配置属性都会影响到后续loadModelToApp方法的执行,loadModelToApp具体参考egg-mongoose/lib/mongoose.js。 所以呢,我换成以下方式来处理配置合并问题,同https://github.com/eggjs/egg/issues/4429#issuecomment-677479416

require('extend2')(true, app.config, extendConfig);