Google Cloud函数中的全局范围变量初始化

时间:2019-02-20 11:12:15

标签: node.js google-cloud-functions google-cloud-kms

我想使用Google Cloud KMS存储一个密钥,并在Google Cloud Function中使用它。首先,我将加密我的密钥并将其存储在环境变量中

如果我解密link之类的密钥,它将返回Promise。 部署并调用函数时,是否可以保证变量完成初始化?

1 个答案:

答案 0 :(得分:1)

我是该代码段和corresponding blog post的作者。对于帖子历史,这是OP所指的完整代码段:

const cryptoKeyID = process.env.KMS_CRYPTO_KEY_ID;

const kms = require('@google-cloud/kms');
const client = new kms.v1.KeyManagementServiceClient();

let username;
client.decrypt({
  name: cryptoKeyID,
  ciphertext: process.env.DB_USER,
}).then(res => {
  username = res[0].plaintext.toString().trim();
}).catch(err => {
  console.error(err);
});

let password;
client.decrypt({
  name: cryptoKeyID,
  ciphertext: process.env.DB_PASS,
}).then(res => {
  password = res[0].plaintext.toString().trim();
}).catch(err => {
  console.error(err);
});

exports.F = (req, res) => {
  res.send(`${username}:${password}`)
}

由于Node是一种异步语言,因此不能保证变量usernamepassword在编写函数调用之前已完全初始化。在该代码段中,我优化了“在函数启动时解密,以便每个函数调用都在恒定时间内运行”。在您的示例中,您要优化“在调用之前函数已完全初始化”,这需要对代码进行一些重新组织。

一种可能的解决方案是将查找移动到调用GCF函数时调用的Node函数中。例如:

const cryptoKeyID = process.env.KMS_CRYPTO_KEY_ID;

const kms = require('@google-cloud/kms');
const client = new kms.v1.KeyManagementServiceClient();

let cache = {};

const decrypt = async (ciphertext) => {
  if (!cache[ciphertext]) {
    const [result] = await client.decrypt({
      name: cryptoKeyID,
      ciphertext: ciphertext,
    });
    cache[ciphertext] = result.plaintext;
  }

  return cache[ciphertext];
}

exports.F = async (req, res) => {
  const username = await decrypt(process.env.DB_USER);
  const password = await decrypt(process.env.DB_PASS);
  res.send(`${username}:${password}`)
}

请注意,我在此处添加了一个缓存层,因为您可能不想在每次调用该函数时解密加密的blob。