使用Express和Passport时出现req.isAuthenticated不是函数的错误
解决
req.isAuthenticated is not a function错误的思路 核心问题1:缺少Passport初始化中间件
Passport必须通过passport.initialize()中间件向req对象注入isAuthenticated()等核心方法,你的代码只配置了passport.session(),漏掉了这关键一步。
需要在app.use(session(...))之后、app.use(passport.session())之前添加:
app.use(passport.initialize());
核心问题2:自定义认证逻辑的偏差
你自己写的isAuthenticated函数检查req.session.user,但Passport认证后会把用户信息存在req.user里,官方提供的req.isAuthenticated()会自动判断用户是否完成认证流程,更可靠。
把自定义中间件替换为:
function isAuthenticated(req, res, next) { if (req.isAuthenticated()) { return next(); } res.status(401).send('请先登录'); // 或返回跳转、错误信息 }
额外小问题修正
- LocalStrategy的错误处理:当前代码未处理账号密码不匹配的情况,会导致请求挂起,补充完善:
passport.use(new LocalStrategy( { usernameField: 'email' }, (email, password, done) => { console.log('Inside local strategy callback') const user = users.find(u => u.email === email); if (!user) { return done(null, false, { message: '用户不存在' }); } if (password !== user.password) { return done(null, false, { message: '密码错误' }); } return done(null, user); } ));
- deserializeUser的返回值规范:找不到用户时应返回
null而非false,避免后续逻辑异常:
passport.deserializeUser((id, done) => { console.log('Inside deserializeUser callback') console.log(`The user id passport saved in the session file store is: ${id}`) const user = users.find(u => u.id === id); done(null, user || null); });
修改后的关键代码片段
// ... 导入和Passport配置部分不变 const app = express(); app.enable('trust proxy') app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.use(session({ genid: (req) => { console.log('Inside the session middleware') console.log(req.sessionID) return uuid() // use UUIDs for session IDs }, store: new FileStore(), secret: 'keyboard cat', resave: false, saveUninitialized: true })) // 新增Passport初始化中间件 app.use(passport.initialize()); app.use(passport.session()); // ... 登录路由部分不变 // 替换为官方认证逻辑的中间件 function isAuthenticated(req, res, next) { if (req.isAuthenticated()) { return next(); } res.status(401).send('请先登录'); } app.get('/authrequired', isAuthenticated, function (req, res) { res.send('you hit the authentication endpoint\n') }) // ... 静态文件和服务器配置部分不变
内容的提问来源于stack exchange,提问作者Ruffyg
相关产品推荐
相关产品推荐

