MongoDB用户数据更新求助:前端调用接口及Cookie身份验证问题
解决方案
一、后端实现Cookie跟踪登录用户
要通过Cookie识别登录用户,需先配置Cookie解析中间件,再在登录接口设置用户身份Cookie,最后修改/data接口从Cookie获取用户ID。
- 安装并引入Cookie解析中间件
npm install cookie-parser
在项目入口文件(如app.js)中添加:
const cookieParser = require('cookie-parser'); app.use(cookieParser());
- 修改登录接口,登录成功后设置身份Cookie
假设你的登录接口逻辑如下,在验证通过后将用户ID写入Cookie:
app.post('/login', async (req, res) => { // 用户名密码验证逻辑 const user = await userCollection.findOne({ username: req.body.username }); if (user && /* 密码校验通过 */) { // 设置HttpOnly Cookie,防止XSS攻击,有效期设为1天 res.cookie('userId', user._id.toString(), { httpOnly: true, maxAge: 24 * 60 * 60 * 1000, sameSite: 'strict' // 降低CSRF风险 }); res.json({ success: true, username: user.username }); } else { res.status(401).json({ message: '登录失败' }); } });
- 优化
/data接口,从Cookie获取用户ID
不再通过URL参数传递用户ID,直接从Cookie读取:
app.post('/data', async (req, res) => { try { const { taskCount, coinCount, soldItems } = req.body; const userId = req.cookies.userId; // 未登录拦截 if (!userId) { return res.status(401).json({ message: "未登录,请先登录" }); } // 若使用原生MongoDB驱动,需将字符串转为ObjectId // const { ObjectId } = require('mongodb'); // const user = await userCollection.findOne({ _id: new ObjectId(userId) }); // 若使用Mongoose,直接传字符串即可自动转换 const user = await userCollection.findOne({ _id: userId }); if (!user) { return res.status(404).json({ message: "用户不存在" }); } await userCollection.updateOne( { _id: userId }, { $set: { taskCount, coinCount, soldItems } } ); res.json({ taskCount, coinCount, soldItems, username: user.username, userid: user._id }); } catch (error) { console.error("更新数据时出错:", error); res.status(500).json({ message: "服务器内部错误" }); } });
二、前端调用接口同步数据
从localStorage取出计数数据,通过fetch或axios发送POST请求,注意携带Cookie以验证用户身份。
用fetch实现
// 同步数据到数据库的函数 async function syncUserData() { // 从localStorage读取数据,转成数字类型 const taskCount = parseInt(localStorage.getItem('taskCount')) || 0; const coinCount = parseInt(localStorage.getItem('coinCount')) || 0; const soldItems = parseInt(localStorage.getItem('soldItems')) || 0; try { const response = await fetch('/data', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ taskCount, coinCount, soldItems }), credentials: 'include' // 携带Cookie }); const result = await response.json(); if (response.ok) { console.log('数据同步成功:', result); // 可在此添加用户提示或状态更新逻辑 } else { console.error('数据同步失败:', result.message); } } catch (error) { console.error('请求出错:', error); } } // 调用时机示例:页面卸载前自动同步 window.addEventListener('beforeunload', syncUserData); // 或绑定按钮点击事件 // document.getElementById('sync-btn').addEventListener('click', syncUserData);
用axios实现
async function syncUserData() { const taskCount = parseInt(localStorage.getItem('taskCount')) || 0; const coinCount = parseInt(localStorage.getItem('coinCount')) || 0; const soldItems = parseInt(localStorage.getItem('soldItems')) || 0; try { const response = await axios.post('/data', { taskCount, coinCount, soldItems }, { withCredentials: true // 携带Cookie }); console.log('数据同步成功:', response.data); } catch (error) { console.error('数据同步失败:', error.response?.data?.message || error.message); } }
三、关键注意事项
- Cookie安全:生产环境建议开启
secure: true(仅HTTPS下传输Cookie),进一步提升安全性。 - 数据类型校验:
localStorage存储的是字符串,必须转为数字后再传给后端,避免数据库存入非预期的字符串类型。 - 错误处理:前端需处理未登录、服务器错误等场景,给用户清晰的反馈提示。
内容的提问来源于stack exchange,提问作者Jacob Mitchell
相关产品推荐
相关产品推荐

