如何在页面展示MongoDB用户数据、编辑保存并正确获取当前登录用户
问题1:如何获取当前登录用户数据
你当前GET /users/me返回第一条用户数据的核心原因是没有做登录身份校验,也没有根据登录凭证查询对应账号,按以下步骤修改:
- 新增身份认证中间件
先在项目中新建middleware/auth.js文件,用于解析登录时存的cookie、校验登录状态、挂载当前登录用户到请求对象:
const jwt = require('jsonwebtoken') const User = require('../models/user') // 替换为你自己的User模型路径 const auth = async (req, res, next) => { try { // 读取登录时存的auth_token cookie const token = req.cookies.auth_token if (!token) throw new Error() // 解密token,第二个参数替换为你生成jwt时用的密钥 const decoded = jwt.verify(token, process.env.JWT_SECRET) // 匹配对应用户(默认你生成token时已经将token存入用户的tokens数组字段) const user = await User.findOne({ _id: decoded._id, 'tokens.token': token }) if (!user) throw new Error() // 挂载当前用户到req对象,后续路由可直接读取 req.user = user next() } catch (e) { res.status(401).send({error: '请先登录'}) } } module.exports = auth
- 修改
GET /users/me路由
引入上面写的auth中间件,直接返回已经挂载好的当前用户即可:
const auth = require('../middleware/auth') // 引入中间件 router.get("/users/me", auth, async (req, res) => { try { res.send(req.user) } catch (e) { res.status(500).send() } })
问题2:点击更新按钮跳转JSON页面修复
这个问题有三个错误点:form触发了默认提交行为、POST路由响应逻辑错误、AJAX提交逻辑缺失,按以下步骤修改:
- 修改HTML表单
取消form的默认提交配置,给提交按钮单独绑定点击事件:
<div class="centered"> <h2>Profile page</h2> <form id="profileForm"> <table id="profile"> <thead></thead> <tbody id="addData"> </tbody> </table> <button type="button" class="btn btn-primary" id="updateBtn">Update account</button> <a href="/login"><button type="button" class="btn btn-danger" id="btn-profile" onclick="deleteUser()">Delete account</button></a> </form> </div>
- 修复
POST /users/me路由
加上auth中间件,删除重复的响应逻辑(res.send和res.redirect不能同时使用,响应只能返回一次):
router.post("/users/me", auth, async (req, res) => { const updates = Object.keys(req.body) const allowedUpdates = ["name", "email", "password", "age"] const isValidOperation = updates.every((update) => allowedUpdates.includes(update)) if (!isValidOperation) { return res.status(400).send({ error: "Invalid updates!" }) } try { updates.forEach((update) => req.user[update] = req.body[update]) await req.user.save() // AJAX提交返回成功状态即可,不需要redirect res.send({success: true}) } catch (e) { res.status(400).send(e) } })
- 修改前端JS逻辑
- 首先修改查询用户数据的逻辑,给input加上name属性,方便提交时读取值,同时不要展示明文密码
- 新增更新按钮的点击提交逻辑,删除原来没用的
editProfile自执行函数
// 查询用户数据逻辑 (async function getProfile() { try { $.ajax({ method: "GET", url: "/users/me", dataType: "json" }).done(function (user) { $("#addData") .append(`<tr><td>用户名</td><td><input name="name" value="${user.name}"></td></tr>`) .append(`<tr><td>邮箱</td><td><input name="email" value="${user.email}"></td></tr>`) .append(`<tr><td>密码</td><td><input name="password" type="password" placeholder="留空则不修改"></td></tr>`) }) } catch (error) { console.log(error); } })(); // 绑定更新按钮点击事件 $('#updateBtn').on('click', function() { const formData = $('#profileForm').serialize() $.ajax({ method: "POST", url: "/users/me", data: formData, success: function() { alert('修改成功') window.location.reload() }, error: function(e) { alert('修改失败:' + e.responseText) } }) })
额外优化建议
在User模型中添加toJSON方法,自动过滤返回数据中的敏感字段,避免泄露密码、token等信息:
userSchema.methods.toJSON = function() { const userObj = this.toObject() delete userObj.password delete userObj.tokens return userObj }
内容的提问来源于stack exchange,提问作者Jake.L.B
相关产品推荐
相关产品推荐

