【发布时间】:2019-11-08 16:34:24
【问题描述】:
使用 IAM 数据库身份验证,密码将在大约 15 分钟后过期。因此,理想情况下,我必须在密码过期之前更新数据库连接。我在数据库的第一次初始化时设置了一个计时器,并在每个查询中查询经过的时间。如何在密码过期之前刷新连接的密码?或者我怎样才能销毁旧的数据库对象并在必要时更新对象?
错误消息是:“用户 iam_user 的 PAM 身份验证失败”。
获取IAM密码的代码:
const pgp = require('pg-promise')();
const AWS = require('aws-sdk');
const ca =
'-----BEGIN CERTIFICATE-----\nMIID9DCCAtyg...
...wZfTUU=\n-----END CERTIFICATE-----\n';
const signer = new AWS.RDS.Signer({
region: process.env.REGION,
username: process.env.DATABASE_USER,
hostname: process.env.DATABASE_HOST,
port: parseInt(`${process.env.DATABASE_PORT}`, 10),
});
module.exports = pgp({
host: process.env.DATABASE_HOST,
port: process.env.DATABASE_PORT,
database: process.env.DATABASE_NAME,
user: process.env.DATABASE_USER,
ssl: { ca },
dialectOptions: { ssl: { require: true } },
password: signer.getAuthToken(),
});
将 db 对象注入到 graphql:
const db = require('../db/init');
server.use(
mount(
'/graphql',
graphqlHTTP( () => ({
schema: schema,
context: { startTime: Date.now(), db },
graphiql: true
})),
),
);
在解析器中使用数据库。
我可以查询数据库连接的创建时间。如有必要,是否可以更新密码?或者销毁旧数据库对象并创建新数据库对象的最佳方法是什么?
const resolvers = {
Query: {
Post: (root, args, {db}) => {
console.log(args.id);
console.log(db.$config.options)
const postQuery = new PQ({
text:
'SELECT post_id as id FROM tbl_post where post_id = $1',
values: [parseInt(args.id, 10)],
});
return db.one(postQuery).catch((err) => console.log(err));
}
}
【问题讨论】:
-
数据库连接和你的密码过期有什么关系?
-
您好,vitally-t,首先我要感谢您提供的出色图书馆,您对每个寻求帮助的人都非常有帮助。据我了解文档,我可以使用 database.$cn 访问(只读)连接设置。但我无法更新数据库连接中的密码。所以我试图用 pgp.end() / db.$pool.end() 结束池并重新创建池。但是当压力测试时我得到连接超时。所以我想知道是否有更好的方法只更改打开的数据库对象中的密码,我用 signer.getAuthToken() 更新。
-
为什么不能只使用一个函数作为密码?这就是它的作用,提供动态密码。
-
密码功能仅在新连接时调用。这个想法是,当数据库密码过期时,连接不再有效,即断开,在这种情况下连接失败,然后自动分配,同时获得新密码。不应该无缘无故地调用密码函数,因为您正在使用一个缓存实时连接的连接池。由于您使用的是 GraphQL,也许我就是您应该咨询的人群。
-
如果我以小于 10 秒的间隔重复连接,则密码不会通过该功能更新,但连接确实保持打开状态。如果我以大于 10 秒的间隔重复连接,则每次调用都会调用密码更新功能。无论哪种方式,这都有效。感谢您的帮助。
标签: aws-sdk pg-promise