You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Passport+Express-Session认证异常:req.user未定义且req.isAuthenticated()非函数

Passport LocalStrategy认证异常:req.user未定义且req.isAuthenticated()不存在

问题详情

我使用Passport结合express-session实现身份认证,采用LocalStrategy。Passport的deserializeUser函数能正常获取到用户,但回调函数done要么没能设置req.user,要么在执行setUserAuthentication中间件(该中间件负责将res.locals.user设为req.user)之前,req.user就被清除了。

我查阅了大量同类问题,了解到需要保证中间件顺序正确,目前我的中间件顺序看起来没问题:在session、passport.initialize()、passport.session()之后才挂载路由。

服务器代码(index.js)

app.use(express.urlencoded({extended : false}));
app.use(cookieParser());
app.use(express.static('./assets'));
app.use(layout);
app.set('view engine' , 'ejs');
app.set('views','./views');
app.set('layout','./layouts');
app.use(session({
    name : 'user_key',
    secret : 'anything',
    saveUninitialized : false,
    resave : false,
    
    cookie : {
        maxAge : (1000*60*100)
    }
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(passport.setUserAuthentication);
app.use('/' , require('./routes'));

Passport配置文件(config/passport-local-strategy.js)

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const User = require('../models/user');

passport.use(new LocalStrategy(
    {
        usernameField : 'email'
    },
    function(email , password , done){
    
        User.findOne({email : email},function(err , user){
            if(err){
                console.log('error in finding user');
                return done(err);
            }
            if(!user || user.password != password){
                console.log('invalid credentials');
                return done(null,false);
            }
            return done(null,user);
            
        })
    }
))

passport.serializeUser(function(user,done){
    done(null,user.id);
});
passport.deserializeUser(function(id,done){
    // console.log(id);
    User.findById(id,(err,user)=>{
        if(err){
            console.log('error in finding user');
            return done(err);
        }
       return done(null,user);

    })
});

passport.checkAuthentication = function(res,req,next){
    if(req.isAuthenticated()){
       return  next();
    }
    else res.redirect('/users/sign-in');
}
passport.setUserAuthentication = function(res,req,next){
   
    if(req.isAuthenticated()){
        res.locals.user = req.user;
    }
    next();
}

module.exports = passport;

目录结构

config / passport-local-strategy.js
controller/user_handler.js
routes/user.js
index.js(服务器入口)

当前报错

req.user is undefined 且 req.isAuthenticated() is not a function


解决办法

问题出在自定义中间件的参数顺序错误:Express中间件的标准参数顺序是 (req, res, next),但你写的checkAuthentication和setUserAuthentication把res放在了第一个参数的位置。

这会导致:

  1. 你调用的req.isAuthenticated()实际上是在res对象上调用,而res并没有这个方法,所以报错req.isAuthenticated() is not a function。
  2. 你访问的req.user实际是res对象,自然返回undefined,无法正确赋值给res.locals.user。

修正后的中间件代码:

passport.checkAuthentication = function(req, res, next){
    if(req.isAuthenticated()){
       return next();
    }
    res.redirect('/users/sign-in');
}
passport.setUserAuthentication = function(req, res, next){
    if(req.isAuthenticated()){
        res.locals.user = req.user;
    }
    next();
}

另外提醒:当前session配置使用默认的内存存储,生产环境下会导致内存泄漏,建议更换为如connect-mongo这类持久化存储方案,但这不是本次报错的直接原因。


内容的提问来源于stack exchange,提问作者Vivek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 08:15:36