如何在Mongoose中为不同文档设置不同的过期时间?
MongoDB实现动态过期的令牌文档
要实现根据令牌类型动态设置过期时间,不能用Schema里固定的expires参数,得换用基于日期字段的TTL索引来实现,具体步骤如下:
1. 修改Schema定义
定义一个expireAt日期字段,并给它设置TTL索引,将expires设为0,让MongoDB根据字段里的具体日期来触发自动删除:
const mongoose = require('mongoose'); const TokenSchema = new mongoose.Schema({ token: String, type: String, expireAt: { type: Date, index: { expires: 0 } // 由字段值的日期决定过期时间 } }); const Token = mongoose.model('Token', TokenSchema);
2. 动态计算过期时间
创建令牌时,根据类型计算对应的过期时长,再生成具体的过期日期赋值给expireAt:
// 根据令牌类型返回对应的过期秒数 function getExpireSeconds(type) { switch(type) { case 'access': return 3600; // 访问令牌1小时过期 case 'refresh': return 86400 * 7; // 刷新令牌7天过期 case 'verify': return 1800; // 验证令牌30分钟过期 default: return 3600; // 默认1小时 } } // 创建并保存令牌 async function createAndSaveToken(tokenStr, tokenType) { const expireMs = getExpireSeconds(tokenType) * 1000; const expireAt = new Date(Date.now() + expireMs); const newToken = new Token({ token: tokenStr, type: tokenType, expireAt }); await newToken.save(); return newToken; }
原理说明
MongoDB的TTL索引会定期扫描文档,当expireAt字段的日期早于当前时间时,自动删除该文档。这种方式能灵活控制每个文档的过期时间,完全满足不同令牌类型的差异化过期需求。
注意事项
- MongoDB默认开启TTL清理线程,不需要额外配置;如果手动关闭过,需要重新开启
- 计算过期日期时要注意单位转换,
Date.now()返回的是毫秒数,所以要把秒数乘以1000 - 如果后续需要修改令牌的过期时间,直接更新
expireAt字段即可,TTL索引会自动识别新的过期时间
内容的提问来源于stack exchange,提问作者ololo
相关产品推荐
相关产品推荐

