MySQL Express-mysql-session 阻止 passport deserializeUser 运行的解决方法
最近在使用 Express 及其扩展模块 MySQL 和 passport 进行用户认证时,遇到了一个问题:passport deserializeUser 方法无法正常运行。经过排查,发现是使用了 express-mysql-session 这一中间件导致的问题。本文将介绍这个问题的解决方法。
阅读更多:MySQL 教程
问题描述
在使用 passport 进行用户认证时,我们需要实现 serializeUser 和 deserializeUser 两个方法。其中,serializeUser 方法是在登录成功后将用户信息存入 session 中,而 deserializeUser 方法则是在后续请求中从 session 中读取用户信息。一般情况下,我们会使用 passport 自带的 session 策略来管理 session,例如:
app.use(session({ secret: 'xxx', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());
然而,如果我们使用了 express-mysql-session 这一中间件来将 session 存储到 MySQL 数据库中,就会遇到 deserializeUser 方法无法正常运行的问题。具体表现为,在每个请求中,passport 都会认为用户未登录,并将用户重定向到登录页面。
问题原因
经过分析源代码,我们发现该问题的原因在于 express-mysql-session 中设置了 session 的 touchAfter 属性为固定的 0,即指定用户在每次请求中都不需要刷新 session。而 passport 在每次请求中会根据 session 的更新时间判断用户是否登录,因此一直认为用户未登录。
解决方法
解决这个问题的方法非常简单,只需要在使用 express-mysql-session 中间件时,显式地将 touchAfter 属性设置为一个大于 0 的值即可。例如:
const MySQLStore = require('express-mysql-session')(session);
const sessionStore = new MySQLStore({
host: 'localhost',
user: 'root',
password: 'xxx',
database: 'test',
touchAfter: 3600 // 每小时刷新一次
});
app.use(session({
secret: 'xxx',
resave: false,
saveUninitialized: false,
store: sessionStore // 使用自定义的 MySQLStore
}));
app.use(passport.initialize());
app.use(passport.session());
总结
在使用 express-mysql-session 中间件时,一定要注意其 touchAfter 属性的设置。如果设置不当,可能会造成 passport deserializeUser 方法无法正常运行的问题。通过设置一个合适的值,可轻松解决该问题,从而确保 passport 可以正常读取 session 中的用户信息。
极客笔记