Next.js技术问题:如何将卡组关联至当前登录用户
问题:Next-Auth用户无法与MongoDB中保存的卡组关联
目标
开发网站功能:登录用户在「Deck editor」页面用数据库卡牌创建卡组,保存时关联个人账户,方便后续登录调取。
当前问题
卡组能保存至数据库,但无法关联当前用户。最初数据库无by关联字段,重启项目后字段出现,但关联逻辑仍不生效。
已完成功能
- Deck editor仅登录用户可访问
- 卡牌搜索功能正常
- 点击搜索结果添加卡牌至卡组,点击已添加卡牌可移除
- 支持切换「Main」「Side」两种卡组类型
技术栈
Next.js、MongoDB(mongoose连接)、Material UI、Next-Auth
核心代码片段
deckEditing.jsx(前端保存逻辑)
import { useSession } from "next-auth/react"; const DeckEditor = () => { const { data: session } = useSession(); const saveDeck = async () => { const deckData = { name: deckName, main: mainDeck, side: sideDeck, by: session?.user?.id // 尝试传入用户ID }; await fetch("/api/saveDeck", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(deckData) }); }; };
saveDeck.js(API路由)
import Deck from "../../models/deck"; import { connectDB } from "../../utils/db"; import { getServerSession } from "next-auth/next"; import { authOptions } from "./auth/[...nextauth]"; export default async function handler(req, res) { if (req.method !== "POST") return res.status(405).end(); await connectDB(); const session = await getServerSession(req, res, authOptions); if (!session) return res.status(401).json({ message: "未授权" }); const { name, main, side } = req.body; const newDeck = new Deck({ name, main, side, by: session.user.id // 关联用户ID }); try { await newDeck.save(); res.status(201).json({ message: "卡组保存成功" }); } catch (err) { res.status(500).json({ message: "保存失败", error: err.message }); } }
deck.js(Mongoose卡组模型)
import mongoose from "mongoose"; const deckSchema = new mongoose.Schema({ name: { type: String, required: true }, main: { type: Array, required: true }, side: { type: Array, required: true }, by: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true } // 关联User模型 }); export default mongoose.models.Deck || mongoose.model("Deck", deckSchema);
user.js(Mongoose用户模型)
import mongoose from "mongoose"; const userSchema = new mongoose.Schema({ id: { type: String, required: true }, name: { type: String }, email: { type: String, required: true, unique: true } }); export default mongoose.models.User || mongoose.model("User", userSchema);
排查修复步骤
确认Session中用户ID的正确性
- 在前端打印
session?.user,检查是否存在id字段:console.log(session?.user); - 若使用OAuth登录(如Google),Next-Auth默认用户标识是
sub字段,需在[...nextauth].js的回调中映射为id:callbacks: { async session({ session, user }) { session.user.id = user.id || user.sub; return session; } }
- 在前端打印
强制在API路由获取用户ID(避免前端篡改)
- 不要依赖前端传入的
by字段,必须通过getServerSession在后端获取用户ID,确保安全性。 - 检查
authOptions是否正确导入,getServerSession能否正常返回会话数据。
- 不要依赖前端传入的
验证Mongoose关联字段配置
- 若User模型使用MongoDB默认的
_id(而非自定义id),需调整卡组模型的关联字段:// deck.js中修改by字段 by: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true } // 同时在Next-Auth的session回调中返回用户的_id字符串: callbacks: { async session({ session, user }) { session.user.id = user._id.toString(); return session; } } - 确保
ref的值与User模型的名称完全一致(区分大小写)。
- 若User模型使用MongoDB默认的
查看数据库保存错误日志
- 在
saveDeck.js的catch块中打印详细错误,排查是否存在字段类型不匹配或必填项缺失:catch (err) { console.error("卡组保存错误:", err); res.status(500).json({ message: "保存失败", error: err.message }); }
- 在
确认用户已存入数据库
- 检查MongoDB的
users集合,确保登录用户已被正确创建,且其id(或_id)与Session中的值一致。
- 检查MongoDB的
内容的提问来源于stack exchange,提问作者TC_neva
相关产品推荐
相关产品推荐

