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

如何在Express+Passport.js的控制器中全局使用currentUser变量?

在所有Express控制器中便捷访问Passport.js的currentUser

嘿,这个需求挺常见的,其实借助Express的中间件特性,就能轻松实现让所有控制器便捷拿到当前用户信息,给你分享几个实用的方案:

方案一:利用已有的全局中间件直接访问res.locals.currentUser

你已经写了把currentUser传到视图的全局中间件,其实控制器里也能直接访问res.locals.currentUser!这是最省事的方法,不用额外加新代码:

// 你已经配置好的全局中间件
app.use(function(req, res, next){
  res.locals.currentUser = req.user;
  next();
});

// 在任意控制器里直接使用
app.get('/posts', async (req, res, next) => {
  const currentUser = res.locals.currentUser;
  
  // 先处理用户未登录的情况
  if (!currentUser) {
    return res.redirect('/login');
  }

  // 用currentUser做数据库查询,比如检查用户是否点赞过帖子
  const posts = await Post.find({});
  const postsWithLikeStatus = posts.map(post => ({
    ...post.toObject(),
    hasLiked: post.likes.includes(currentUser._id)
  }));

  res.render('posts', { posts: postsWithLikeStatus });
});

方案二:自定义控制器包装函数,自动传入currentUser

如果觉得每次写res.locals.currentUser还是有点繁琐,可以写一个简单的包装函数,把currentUser直接作为参数传给控制器,让代码更简洁:

// 定义一个包装函数,自动注入currentUser
const withCurrentUser = (controller) => {
  return (req, res, next) => {
    // 把Passport提供的req.user作为参数传给目标控制器
    controller(req, res, next, req.user);
  };
};

// 使用包装后的控制器
app.get('/posts', withCurrentUser(async (req, res, next, currentUser) => {
  if (!currentUser) {
    return res.redirect('/login');
  }

  // 直接用currentUser操作数据库
  const userLikedPosts = await Post.find({ likes: currentUser._id });
  // ...其他业务逻辑
  res.render('posts', { likedPosts: userLikedPosts });
}));

关键注意事项

  • 确保你的路由已经通过Passport的认证中间件保护(比如passport.authenticate('local', { session: true })),否则req.user会是undefined,记得在控制器里先判断用户是否登录。
  • 如果是API接口(返回JSON而非渲染视图),两种方案同样适用,只需要把res.render换成res.json即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:06:49