使用Express+JWT+MongoDB时如何获取当前已认证用户数据展示到页面
具体实现步骤
1. 修复登录逻辑的JWT生成错误
你当前登录逻辑中调用createToken时传入的是req.body对象,该对象仅包含邮箱和密码,没有用户ID、登录名等核心字段,生成的JWT payload内容是无效的。需要修改为传入从数据库查询到的真实用户对象:
router.post('/',async (req,res)=>{ const {mail, password } = req.body const isUserExist = await User.findOne({mail:mail}) // 增加空判断避免访问不存在对象的属性时报错 if(!isUserExist){ console.log('用户不存在') return res.redirect('/login') } const UserPwdCorrect = isUserExist.password bcrypt.compare(password,UserPwdCorrect).then((match)=>{ if(!match){ console.log("密码错误") return res.redirect('/login') } // 这里改为传入数据库查询到的isUserExist,而非req.body const accessToken = createToken(isUserExist) res.cookie("token",accessToken,{ maxAge:60*60*24*30*1000 }) res.redirect('/') }) })
2. 改造JWT校验中间件,挂载用户信息到请求对象
原validateToken中间件仅标记了认证状态,没有将JWT解析出的用户信息挂载到请求对象上,修改如下:
const validateToken = (req,res,next) =>{ const accessToken = req.cookies["token"] // 初始化属性避免后续取值时报undefined错误 req.user = null req.authenticated = false if(!accessToken) return next() try { const validtoken = verify(accessToken,"jwt-secret") if(validtoken){ req.authenticated = true // 把解析到的用户信息挂载到req.user上,后续所有路由都可以直接读取 req.user = validtoken } return next() } catch(err){ console.log(err) return next() } }
3. 路由中使用中间件获取用户信息
在需要展示登录用户信息的路由上引入validateToken中间件,直接从req.user中取值即可,示例如下:
// 首页路由,先经过校验中间件处理 router.get('/', validateToken, async (req, res) => { // 如果需要获取数据库中最新的用户信息(比如用户近期修改过昵称等资料),可以用ID主动查库 // const latestUser = await User.findById(req.user?.id) // 渲染页面时传入用户信息,以EJS模板为例 res.render('index', { user: req.user // 需要最新数据就替换为latestUser }) })
4. 页面渲染展示登录名
在模板中判断用户登录状态,展示对应登录名即可,以EJS为例:
<% if(user) { %> <span>当前登录用户:<%= user.login %></span> <% } else { %> <a href="/login">登录</a> <% } %>
内容的提问来源于stack exchange,提问作者GDTyka
相关产品推荐
相关产品推荐

