SetTimeout在Mongoose架构中间件中不起作用

问题描述 投票:1回答:1

我想在生成forgetpassword_token 24小时后,在mongodb文件中将null更新为forgetpassword_token。所以我使用Mongoose架构中间件和setTimeout,但setTimeout不工作。

我试图实现async await,这也不符合我的结果。

CompanySchema.post('updateOne',true, function(doc,next){
    next();
       setTimeout(this.update({},{ $set: { forgetpassword_token: null } }).then(result=>{
           console.log(result);
                   }),10000000000);
       });
node.js settimeout mongoose-schema
1个回答
2
投票

这里的主要问题是这个实现是有缺陷的,因为如果你的节点应用程序在24小时窗口期间重新启动,你的超时将消失(是一个内存对象,而不是持久化),令牌将保持活动状态,让你暴露在安全性之下风险。

手动令牌验证

一个非常常见的解决方案是将token_expiration_date与令牌一起保存,在相关密码重置请求期间进行日期比较。如果token_expiration_date过期,请求将返回错误,服务器必须删除db上的令牌。

您也可以反过来:将token_creation_datemax-token-ttl存储在您的应用代码中(例如24小时)。在任何情况下,您都可以在请求时进行日期比较。

@NikKyriakides建议(参见评论)这种方法的更复杂的版本:你创建一个JWT的单个contains itself the expiration date令牌。当用户请求重置密码页面时,如果令牌有效,则只需要verify调用单个方法(无手动日期比较)。

Mongo过期选项

更优雅和有效的解决方案是为您的forgetpassword_token创建不同的mongoose模式,并使用本机mongo / mongoose expire option在创建后的固定时间后自动删除文档。

const secondsInADay = 60 * 60 * 24;

const tokenSchema = mongoose.Schema({
    value: String
}, {timestamps: true});

tokenSchema.index({createdAt: 1},{expireAfterSeconds: secondsInADay});
const Token = mongoose.model('Token', tokenSchema);

然后向现有的CompanySchema添加对此架构的引用:

forgetpassword_token: {type: mongoose.Schema.Types.ObjectId, ref: 'Token'}

关于this topic存在很多问题,所以请与相关的mongoose documentation一起检查它们。

作业调度程序

另一种方法是使用像agenda这样的作业调度程序来每小时检查过期的令牌并删除它们。是的,您可以将基于setTimeout的检查编写为您的应用程序的模块,但如果存在正确的工具,为什么不使用它?另请参阅下面的@NikKyriakides评论,了解此解决方案的潜在缺点。

© www.soinside.com 2019 - 2024. All rights reserved.