个人网站用户数据获取疑问:从DB查询还是req.user读取?
问题
我正在做一个提升编程能力的网站,开发用户profile页面时对用户数据获取方式存疑。
我觉得当前的userDetails控制器代码不够安全,因为同时在中间件中通过session的req.user获取用户信息。担心通过数据库查询获取数据时,任何人都能访问,存在安全隐患。
userDetails控制器代码:
module.exports.userDetails = async (req,res,next) => { const {username} = req.params; const user = await User.findOne({username}).populate({path: 'campgrounds'}) console.log(user) if(!user){ req.flash('error', 'Cannot access that username.') return res.redirect('/campgrounds') } res.render('users/details.ejs', {user}) }
中间件代码:
app.use((req,res,next) => { res.locals.currentUser = req.user; res.locals.currentUserDetails = req.user._doc; res.locals.success = req.flash('success'); res.locals.error = req.flash('error'); next(); })
解决方案建议
拆分公开/私有数据:先明确profile页面哪些数据是所有人可看的(比如用户名、公开的campgrounds),哪些是仅限用户本人查看的(比如邮箱、隐私设置)。查询数据库时用
select方法限制返回字段,避免敏感数据泄露,示例:const user = await User.findOne({username}) .select('username campgrounds avatar') // 只取公开字段 .populate({path: 'campgrounds'});加权限校验逻辑:在控制器里判断访问者身份,按需返回数据:
module.exports.userDetails = async (req,res,next) => { const {username} = req.params; const user = await User.findOne({username}).populate({path: 'campgrounds'}); if(!user){ req.flash('error', 'Cannot access that username.') return res.redirect('/campgrounds') } // 判断是否是用户本人访问 const isOwnProfile = req.user && req.user._id.toString() === user._id.toString(); // 非本人访问时过滤敏感字段 const displayUser = isOwnProfile ? user : { username: user.username, campgrounds: user.campgrounds, // 只保留允许公开的字段 }; res.render('users/details.ejs', {user: displayUser}) }不要直接暴露req.user._doc:中间件里
res.locals.currentUserDetails = req.user._doc风险很高,_doc包含Mongoose文档的原始数据,可能有密码哈希、邮箱等敏感内容。建议只提取需要的字段赋值:res.locals.currentUserDetails = { id: req.user._id, username: req.user.username, avatar: req.user.avatar };可选:强制登录访问:如果所有profile页面都需要登录才能查看,加一个登录验证中间件:
const isLoggedIn = (req, res, next) => { if(!req.isAuthenticated()){ req.flash('error', '请先登录!'); return res.redirect('/login'); } next(); } // 给profile路由挂载该中间件 app.get('/users/:username', isLoggedIn, userDetails);
内容的提问来源于stack exchange,提问作者Kelise
相关产品推荐
相关产品推荐

