Node.js中如何从中间件取值并在其他模块函数中使用
问题描述
我在authenticateUser.js中创建了authenticateUser中间件,代码如下:
async function authenticateUser(req, res, next) { const authHeader = req.headers.authorization; if (!authHeader) { return res.status(401).json({ message: 'Unauthorized access!' }); } try { const accessToken = authHeader.split(' ')[1]; // 此处无需await,split为同步操作 const payload = jwt.verify(accessToken, process.env.ACCESS_TOKEN_SECRET); const { email, uid, role } = payload; const user = await UserClient.findOne({ email }); if (!user || user.accessToken !== accessToken) { return res.status(401).json({ message: 'Unauthorized access!' }); } req.role = role; req.email = email; req.uid = uid; next(); } catch (error) { return res.status(401).json({ message: 'Unauthorized access!' }); } }
在路由(如router.get("/user", authenticateUser, async(req,res)=>{}))中,我可以通过const email = req.email;获取用户邮箱,但想在sites.js的addSitesToUser函数中使用该邮箱值。函数代码如下:
async function addSitesToUser() { try { // <-------需要在此处使用email值--------> const userData = await UserClient.findOne({email}); if(!userData.siteList || userData.siteList.length === 0){ const updatedSites = await UserClient.findOneAndUpdate( { email }, { $push: { siteList: { $each: sites } } }, { upsert: true,new: true } ); } else{ const existingSiteIds = userData.siteList.map(site => site.siteId); const newSites = sites.filter(site => !existingSiteIds.includes(site.siteId)); userData.siteList.push(...newSites); await userData.save(); } } catch (error) { console.error('Error adding sites'); } }
我在index.js中通过await addSitesToUser();调用该函数,请问如何在addSitesToUser中拿到用户邮箱?
解决方案
最直接可靠的方式是将邮箱作为参数传递给addSitesToUser函数,同时补充原函数中缺失的sites参数(原代码中sites未定义会导致报错),具体步骤如下:
1. 修改sites.js中的addSitesToUser函数
让函数接收email和sites两个参数,同时优化逻辑:
async function addSitesToUser(email, sites) { try { const userData = await UserClient.findOne({ email }); if (!userData?.siteList || userData.siteList.length === 0) { await UserClient.findOneAndUpdate( { email }, { $push: { siteList: { $each: sites } } }, { upsert: true, new: true } ); } else { const existingSiteIds = userData.siteList.map(site => site.siteId); const newSites = sites.filter(site => !existingSiteIds.includes(site.siteId)); // 优化:仅当存在新站点时才执行保存操作,减少不必要的数据库请求 if (newSites.length > 0) { userData.siteList.push(...newSites); await userData.save(); } } } catch (error) { // 补充错误详情,方便排查问题 console.error('Error adding sites:', error); } } module.exports = { addSitesToUser }; // 确保函数被导出供外部调用
2. 在调用时传入邮箱和站点数据
如果index.js的调用是在经过authenticateUser中间件的路由处理函数中,直接将req.email和站点数据传入即可:
// index.js中的路由处理逻辑示例 const { addSitesToUser } = require('./sites.js'); router.get("/user", authenticateUser, async(req, res)=>{ // 定义要添加的站点数据 const sites = [ { siteId: 'site_001', name: '站点A' }, { siteId: 'site_002', name: '站点B' } ]; // 调用函数并传入邮箱和站点数据 await addSitesToUser(req.email, sites); // 后续响应逻辑 res.json({ message: '站点添加成功' }); });
额外优化提示
- 原
authenticateUser中const accessToken = await authHeader.split(' ')[1];的await是多余的,split为同步操作,可直接删除。 - 错误捕获时打印具体错误信息,能大幅降低问题排查难度。
内容的提问来源于stack exchange,提问作者Ke_Sandaru
相关产品推荐
相关产品推荐

