Node.js自動清理過期Token的方法步驟
引言
你是否遇到過 Token 過期導(dǎo)致用戶無法登錄的問題?在高并發(fā)場景下,手動清理顯然不是個好主意,自動定時清理才是王道。
業(yè)務(wù)場景
假設(shè)你有一個在線商城,用戶登錄后會生成一個 JWT Token,有效期為 7 天。超過有效期后,Token 應(yīng)該被自動清理,防止數(shù)據(jù)庫膨脹和提高安全性。
技術(shù)選型
- cron:用于定時任務(wù)調(diào)度
- bull:用于任務(wù)隊(duì)列管理
- MongoDB:存儲 Token
實(shí)現(xiàn)步驟
1. 安裝依賴
npm install cron bull mongoose
2. 連接 MongoDB
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/your-database', { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
db.on('error', console.error.bind(console, '連接錯誤:'));
db.once('open', () => {
console.log('數(shù)據(jù)庫連接成功');
});
3. 定義 Token 模型
const tokenSchema = new mongoose.Schema({
token: String,
expiresAt: { type: Date, index: { expires: 1 } }
});
const Token = mongoose.model('Token', tokenSchema);
4. 創(chuàng)建定時任務(wù)
使用 cron 創(chuàng)建一個定時任務(wù),每 1 小時執(zhí)行一次。
const cron = require('cron');
const ClearTokenJob = new cron.CronJob('0 * * * *', async () => {
await Token.deleteMany({ expiresAt: { $lt: new Date() } });
console.log('過期 Token 已清理');
});
ClearTokenJob.start();
5. 使用 Bull 管理任務(wù)隊(duì)列
Bull 可以確保任務(wù)的可靠執(zhí)行,即使 Node.js 進(jìn)程崩潰也能恢復(fù)。
const Queue = require('bull');
const clearTokenQueue = new Queue('clearTokenQueue', 'redis://127.0.0.1:6379');
clearTokenQueue.process(async (job, done) => {
await Token.deleteMany({ expiresAt: { $lt: new Date() } });
console.log('過期 Token 已清理');
done();
});
6. 定時將任務(wù)加入隊(duì)列
結(jié)合 cron 和 bull,確保任務(wù)定時加入隊(duì)列。
const cron = require('cron');
const ClearTokenJob = new cron.CronJob('0 * * * *', () => {
clearTokenQueue.add();
});
ClearTokenJob.start();
7. 監(jiān)控任務(wù)執(zhí)行
使用 Bull 的內(nèi)置監(jiān)控功能,確保任務(wù)執(zhí)行情況。
clearTokenQueue.on('completed', (job, result) => {
console.log(`任務(wù)完成: ${job.id}, 結(jié)果: ${result}`);
});
clearTokenQueue.on('failed', (job, err) => {
console.error(`任務(wù)失敗: ${job.id}, 錯誤: ${err}`);
});
8. 高可用配置
在生產(chǎn)環(huán)境中,確保定時任務(wù)的高可用性。
- Redis 集群:配置 Redis 集群,確保任務(wù)隊(duì)列的高可用性。
- 多實(shí)例:在多臺服務(wù)器上運(yùn)行定時任務(wù),確保任務(wù)不會因?yàn)閱吸c(diǎn)故障而失敗。
9. 部署和測試
部署到生產(chǎn)環(huán)境前,務(wù)必進(jìn)行充分的測試。
- 本地測試:使用
nodemon進(jìn)行本地測試,確保代碼無誤。 - Docker:使用 Docker 部署,確保環(huán)境一致性。
# Dockerfile FROM node:14 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["node", "app.js"]
10. 日志記錄
記錄日志,便于問題排查和監(jiān)控。
const winston = require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
clearTokenQueue.process(async (job, done) => {
try {
await Token.deleteMany({ expiresAt: { $lt: new Date() } });
logger.info('過期 Token 已清理');
done();
} catch (err) {
logger.error(`清理 Token 失敗: ${err}`);
done(err);
}
});
11. 安全性考慮
- Token 簽名:確保 JWT Token 的簽名安全。
- 環(huán)境變量:將敏感信息(如數(shù)據(jù)庫連接字符串)存儲在環(huán)境變量中。
const secret = process.env.SECRET_KEY;
const jwt = require('jsonwebtoken');
const generateToken = (userId) => {
const token = jwt.sign({ userId }, secret, { expiresIn: '7d' });
return token;
};
const verifyToken = (token) => {
try {
const decoded = jwt.verify(token, secret);
return decoded;
} catch (err) {
return null;
}
};
12. 優(yōu)化建議
- 索引優(yōu)化:在
expiresAt字段上添加索引,提高查詢效率。 - 任務(wù)調(diào)度:根據(jù)業(yè)務(wù)需求調(diào)整
cron的調(diào)度頻率。
const tokenSchema = new mongoose.Schema({
token: String,
expiresAt: { type: Date, index: { expires: 1 } } // 添加索引
});
13. 常見問題
- Token 未被清理:檢查
expiresAt字段是否正確設(shè)置。 - 任務(wù)執(zhí)行失敗:查看日志文件,確保 Redis 連接無誤。
14. 其他工具推薦
如果你對 cron 和 bull 的組合感到復(fù)雜,可以考慮使用 Hey Cron。Hey Cron 是一個高性能、易用的定時任務(wù)管理工具,支持多種任務(wù)調(diào)度方式和集成方式,能夠顯著簡化任務(wù)管理的復(fù)雜度。
# 安裝 Hey Cron npm install hey-cron
const { Cron } = require('hey-cron');
const clearTokenCron = new Cron('0 * * * *', async () => {
await Token.deleteMany({ expiresAt: { $lt: new Date() } });
logger.info('過期 Token 已清理');
});
clearTokenCron.start();
15. 總結(jié)
通過上述步驟,你可以在 Node.js 中實(shí)現(xiàn)高效、穩(wěn)定的定時清理過期 Token 功能。結(jié)合 Hey Cron,可以進(jìn)一步簡化任務(wù)管理,提高系統(tǒng)的可維護(hù)性和可靠性。
以上就是Node.js自動清理過期Token的方法步驟的詳細(xì)內(nèi)容,更多關(guān)于Node.js自動清理過期Token的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解如何在NodeJS項(xiàng)目中優(yōu)雅的使用ES6
本篇文章主要介紹了詳解如何在NodeJS項(xiàng)目中優(yōu)雅的使用ES6,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
nodejs+mongodb+vue前后臺配置ueditor的示例代碼
本篇文章主要介紹了nodejs+mongodb+vue前后臺配置ueditor的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
Node.js實(shí)現(xiàn)連接mysql數(shù)據(jù)庫功能示例
這篇文章主要介紹了Node.js實(shí)現(xiàn)連接mysql數(shù)據(jù)庫功能,簡單分析了nodejs連接數(shù)據(jù)庫的操作步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-09-09
Node.js中Bootstrap-table的兩種分頁的實(shí)現(xiàn)方法
這篇文章主要介紹了Node.js中Bootstrap-table的兩種分頁的使用方法,需要的朋友可以參考下2017-09-09

