javascript - 在从对 AWS Secrets Manager 的 API 调用返回后导出节点文件中的数据
问题描述
背景
我将 AWS 中 RDS 的数据库信息存储在 Secrets Manager 中。我正在使用 AWS-SDK 来检索密码和其他数据,以便可以secrets
在运行时创建一个对象。当我尝试创建此对象然后将其导出时,导出的对象始终缺少我希望从 aws-sdk 返回的数据。
我试过的 -
我尝试过使用async await
,但在正确填充所有数据之前它仍在导出对象。
例子
const AWS = require('aws-sdk');
const region = 'us-west-2';
const secretName = 'example/example/example';
let secrets = {
username: '',
password: '',
host: '',
port: '',
database: '',
email: 'example@example.com',
emailPassword: 'SomePassword'
};
const client = new AWS.SecretsManager({
region: region
});
client.getSecretValue({ SecretId: secretName }, async (err, data) => {
if (err) {
throw err;
} else {
const res = await JSON.parse(data.SecretString);
secrets.username = res.username;
secrets.password = res.password;
secrets.host = res.host;
secrets.port = res.port;
secrets.database = res.database;
}
});
module.exports = secrets;
问题
这里明显的问题是没有正确创建承诺,但我不确定为什么我的尝试在文件导出后完成承诺。如果console.log(secrets)
在某些情况下我在另一个文件中,它将输出对象丢失的数据,然后在我console.log(secrets)
进入函数后几秒钟后显示由 promise 返回的数据。
secrets
一旦数据从 AWS 返回并添加到对象中,构建此对象并导出它的正确方法是secrets
什么?
解决方案
根据文档,第二个参数getSecretValue
是回调函数,因此不需要使用 async/await,因为 async/await 是为了与 Promise 一起工作。
删除 async/await 应该可以工作。
client.getSecretValue({ SecretId: secretName }, (err, data) => {
if (err) {
throw err;
} else {
const res = JSON.parse(data.SecretString);
secrets.username = res.username;
secrets.password = res.password;
secrets.host = res.host;
secrets.port = res.port;
secrets.database = res.database;
}
});
但是,您正在secrets
同步导出对象,并且它的属性正在异步设置。
相反,您可以返回一个承诺供您的其他模块使用。
const AWS = require('aws-sdk');
const region = 'us-west-2';
const secretName = 'example/example/example';
let secrets = {
email: 'example@example.com',
emailPassword: 'SomePassword'
};
const client = new AWS.SecretsManager({
region: region
});
const promise = new Promise((resolve, reject) => {
client.getSecretValue({ SecretId: secretName }, async (err, data) => {
if (err) {
reject(err);
} else {
const res = await JSON.parse(data.SecretString);
secrets.username = res.username;
secrets.password = res.password;
secrets.host = res.host;
secrets.port = res.port;
secrets.database = res.database;
resolve(secrets);
}
});
})
module.exports = promise;
然后,在使用这个模块的其他模块中,您可以使用 async/await,因为我们现在有一个 Promise。
import {promise} from "./this-module";
(async () => {
const secrets = await promise;
console.log(secrets);
})();
更新
我不确定这是否可行,但值得一试。此处,module.exports
仅设置后secrets
设置。如果这不起作用,那么我会在 StackOverflow 上提出一个关于如何使用 CommonJS(这是您正在使用的模块格式)导出已解决承诺的新问题。
const AWS = require('aws-sdk');
const region = 'us-west-2';
const secretName = 'example/example/example';
let secrets = {
email: 'example@example.com',
emailPassword: 'SomePassword'
};
const client = new AWS.SecretsManager({
region: region
});
const promise = new Promise((resolve, reject) => {
client.getSecretValue({ SecretId: secretName }, async (err, data) => {
if (err) {
reject(err);
} else {
const res = await JSON.parse(data.SecretString);
secrets.username = res.username;
secrets.password = res.password;
secrets.host = res.host;
secrets.port = res.port;
secrets.database = res.database;
resolve(secrets);
}
});
});
(async () => {
module.exports = await promise;
})();
推荐阅读
- c# - C#如何检测按下了哪个键盘?
- python - 运行 bashoperator 时气流重置环境变量
- html - 当视口宽度低于 225 像素时,网格单元会突出
- javascript - 使用 jquery 访问数据列表选项的标签文本
- scala - 没有找到需要的类。这可能是由于您的运行路径中的错误。缺少类:org/apache/http/concurrent/FutureCallback
- facebook - Ionic Facebook 个人资料图片显示非常小
- c# - 如何将变量 var 与 C# 中的枚举进行比较
- php - 在目录中使用多个 htaccess 文件
- salesforce - 如何设置 Salesforce 对象的必填字段?
- java - 石头、纸、剪刀随机匹配不起作用