2

我非常愿意学习是否有更好的“最佳实践”方法来执行此操作,但是我偶尔会运行一些脚本来编辑数据库,因此我需要为这些脚本传递数据库密码。我通过调用调用 google cloud Secrets Manager 的函数来获取密码,但我无法将其添加到 process.env。

例如,如果我把它放在我的脚本文件的顶部:

process.env.DB_HOST='127.0.0.1';
process.env.DB_USER='michael';
process.env.DB_NAME='staging-db';
process.env.DB_PORT=1234;
process.env.DB_PASS= await accessSecret('projects/myproject-123/secrets/DB_PASS/versions/latest');

当上述运行我得到错误
SyntaxError: await is only valid in async functions and the top level bodies of modules

但是,如果我将 process.env.DB_PASS 设置移动到的 async main() 函数中,那么它具有该 main 函数的本地范围。此脚本中的函数调用的其他文件将 process.env.DB_PASS 视为未定义(但请查看文件顶部全局设置的任何 process.env 变量的值。

如何在不将文字秘密实际粘贴到代码中的情况下引入并设置该秘密?

为了表示范围界定的问题,这里是该问题的工作代码再现。这是我正在运行的脚本文件:

process.env.DB_HOST='127.0.0.1';
process.env.DB_USER='michael';
process.env.DB_NAME='staging-db';
process.env.DB_PORT=1234;
const db = require('../../src/database/process_pull_test');


const main = async () => {
  process.env.SCOPED_KEY = "helloimscoped"
  db.hello();
}

main().catch((e) => {console.error(e)});

这是process_pull_test文件

console.log("SCOPED KEY", process.env.SCOPED_KEY);
const dbHost = process.env.DB_HOST;
const dbUser = process.env.DB_USER;
const dbName = process.env.DB_NAME;
const dbPort = process.env.DB_PORT;
const scopedKey = process.env.SCOPED_KEY;

async function hello() {
  console.log(dbHost);
  console.log(dbUser);
  console.log(dbName);
  console.log(dbPort);
  console.log(scopedKey);
  return console.log("Hello Secrets");
}


module.exports = {
  hello: hello
}

而且,这是输出

SCOPED KEY undefined
127.0.0.1
michael
staging-db
1234
undefined
Hello Secrets
4

2 回答 2

2

但是,如果我将 process.env.DB_PASS 设置移动到我的 async main() 函数中,那么它具有该 main 函数的本地范围。此脚本中的函数调用的其他文件将 process.env.DB_PASS 视为未定义(但请查看文件顶部全局设置的任何 process.env 变量的值。

这是不正确的,它将被全局设置。可能只是您的其他文件在您的 main() 运行之前执行。

通常,解决方案是简单地确保在设置环境变量后main(),调用所有其他逻辑。这意味着你所有的逻辑都应该在函数中。

于 2022-01-12T06:33:14.020 回答
1

通常,您使用某种配置工具(例如dotenvconfig)来管理应用程序设置和机密。确保不要将机密文件保存在源代码管理中。

要获取您的数据库机密,您必须在尝试读取任何需要该数据的变量之前对 Google 进行异步调用并获取响应。

我假设您只是从命令行运行它。

首先,您需要一个 async iife 来执行您的 main:

(async () => {
    // you could put your main code here.
    await main();
})();

接下来,向您的 Google 机密管理器添加要求。它可以去任何地方,但你应该确保你可以在你只调用一次的地方访问它。您也可以在主文件中执行此操作。

const gcsm = require('./secretManager');

然后在 main 中调用您的 Google 机密管理器。(我正在编写 api。)并设置您的环境。当您实际将异步代码放入其中时,您还需要等待您对 db.hello() 的调用。从技术上讲,您不需要使用编写的代码来执行此操作。

const main = async () => {
  const dbPassword = await gcsm.getSecret('some config location');
  process.env.DB_PASS = dbPassword;
  process.env.SCOPED_KEY = "helloimscoped"
  await db.hello();
}

在 process_pull_test 的 hello() 中,读取 env 变量。

async function hello() {
  console.log(process.env.DB_PASS);
  console.log(dbHost);
  console.log(dbUser);
  console.log(dbName);
  console.log(dbPort);
  console.log(scopedKey);
  // note the following line doesn't return anything because
  // console.log returns undefined. You probably want to return a 
  // string value to test for now.
  return console.log("Hello Secrets");
}   

这应该让你继续前进。

附加评论:

  • 当您第一次在 process_pull_test 中记录 SCOPED_KEY 时,它没有作用域,它只是在需要时记录并且仍然未定义。
  • 当你登录scopedKeyhello() 时,它仍然是未定义的,因为你在 process_pull_test 顶部的 require 时间设置了它。
  • 当您在 main() 中设置 SCOPED_KEY 时,为时已晚,您已经scopedKey在需要时将其保存为未定义。如果您在记录之前设置scopedKey为hello(),您会看到更新后的值。process.env.SCOPED_KEY
于 2022-01-12T06:33:59.337 回答