Express+Passport.js按用户类型重定向问题:req.user.user_type为undefined
问题:Passport认证后无法获取req.user.user_type,无法按用户类型重定向
我使用Express框架,通过Passport.js和passport-local-mongoose处理用户认证,需求是用户登录后根据类型(医生/患者)重定向到对应仪表盘。但将checkUserType中间件传入passport.authenticate后,执行console.log(req.user.user_type)时输出undefined,无法实现预期逻辑。
以下是我的代码:
var express = require("express"); var router = express.Router(); const userModel = require("./users"); const passport = require("passport"); const localStrategy = require("passport-local").Strategy; const session = require("express-session"); passport.use(new localStrategy(userModel.authenticate())); /* GET home page. */ router.get("/", function (req, res, next) { res.render("intro"); }); router.get("/aboutus", (req, res) => { res.render("aboutus"); }); router.get("/auth", (req, res) => { res.render("login"); }); const checkUserType = (req, res, next) => { const userType = req.user; console.log(userType); if (req.isAuthenticated() && userType === "doctor") { const obj1 = { successRedirect: "/doctorProfile", failureRedirect: "/auth", failureMessage: true, }; return obj1; } else { const obj2 = { successRedirect: "/patientProfile", failureRedirect: "/auth", failureMessage: true, }; return obj2; } }; router.get("/doctorProfile", isLoggedIn, (req, res) => { res.render("doctor"); }); router.get("/patientProfile", isLoggedIn, (req, res) => { res.render("patientProfile"); }); router.post("/register", (req, res) => { var userData = new userModel({ name: req.body.name, username: req.body.username, email: req.body.email, user_type: req.body.user_type, }); userModel.register(userData, req.body.password).then(() => { console.log("You have registered"); res.redirect("/auth"); }); }); function isLoggedIn(req, res, next) { if (req.isAuthenticated()) { return next(); } res.redirect("/auth"); } router.post( "/signin", passport.authenticate("local", checkUserType), (req, res) => {} ); module.exports = router;
解决方案
1. 核心错误:passport.authenticate参数使用错误
你把checkUserType作为passport.authenticate的第二个参数传入,但这个位置应该是配置对象(比如successRedirect、failureRedirect),而不是中间件函数。此时认证还未完成,req.user还未被挂载,自然会输出undefined。
2. 修正步骤
(1)重构checkUserType为认证成功后的中间件
这个中间件要在passport认证完成后执行,此时req.user已经存在:
const checkUserType = (req, res) => { // 直接读取用户类型字段 if (req.user.user_type === "doctor") { res.redirect("/doctorProfile"); } else { res.redirect("/patientProfile"); } };
(2)修改登录路由的中间件顺序
先执行passport.authenticate完成认证,再用checkUserType处理重定向:
router.post( "/signin", passport.authenticate("local", { failureRedirect: "/auth", failureMessage: true }), checkUserType // 认证成功后执行重定向逻辑 );
(3)补充Passport序列化/反序列化配置
你的代码里缺少这部分配置,这会导致req.user无法正确被挂载,必须添加:
// 用passport-local-mongoose提供的序列化/反序列化方法 passport.serializeUser(userModel.serializeUser()); passport.deserializeUser(userModel.deserializeUser());
(4)正确配置express-session
你只require了session但没有配置使用,需要在app.js(或入口文件)中添加session配置,并且要在passport之前挂载:
// 示例配置,根据你的需求调整 app.use(session({ secret: "your-secret-key-here", // 替换为你的密钥 resave: false, saveUninitialized: false })); // 挂载passport中间件 app.use(passport.initialize()); app.use(passport.session());
3. 额外检查
- 确认你的userModel Schema中已经定义了
user_type字段,比如:const userSchema = new mongoose.Schema({ name: String, username: String, email: String, user_type: String // 确保存在该字段 }); - 注册时确认
req.body.user_type确实有值,并且成功存入数据库。
内容的提问来源于stack exchange,提问作者Shree75
相关产品推荐
相关产品推荐

