You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB用户与测验结果集合外键关联及提交异常排查

问题:登录用户测验成绩无法存入关联的MongoDB集合

我前端使用HTML、CSS和JavaScript,后端基于Node.js,数据库采用MongoDB。未添加认证页面时,匿名用户参与测验的成绩可正常存入MongoDB的quizresults集合;添加认证页面后,注册用户的数据能存入user集合,但登录用户提交测验后,成绩仅在页面显示,无法存入quizresults集合。我尝试建立users与quizresults集合的外键关联,但问题仍未解决。

相关代码

user.js

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    }
});

const User = mongoose.model('User', userSchema);

module.exports = User;

quizResult.js

const mongoose = require('mongoose');

const quizResultSchema = new mongoose.Schema({
    user: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User', // Refers to the 'User' model
        required: true
    },
    correctAnswers: {
        type: Number,
        required: true
    },
    totalQuestions: {
        type: Number,
        required: true
    },
    totalScore: {
        type: Number,
        required: true
    }
});

const QuizResult = mongoose.model('QuizResult', quizResultSchema);

module.exports = QuizResult;

authRoutes.js

// authRoutes.js

const express = require('express');
const router = express.Router();
const authController = require('../controllers/authController');

// Route for user registration (POST request)
router.post('/register', authController.register);

// Route for user login (POST request)
router.post('/login', authController.login);

module.exports = router;

userRoutes.js

const express = require('express');
const router = express.Router();
const { authenticateUser } = require('../middlewares/authMiddleware');
const { generateToken } = require('../utils/jwtUtils');

// Placeholder route handler for user login
router.post('/login', authenticateUser, (req, res) => {
    // Handle user login logic here
    // Assuming the user is authenticated, generate a JWT token
    const token = generateToken(req.user.userId);
    // Send the token back to the client
    res.json({ token });
});

module.exports = router;

app.js

const express = require('express');
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
const path = require('path');
const crypto = require('crypto');

const User = require('./models/user');
const authRoutes = require('./routes/authRoutes');

const app = express();

// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/stallman', { useNewUrlParser: true, useUnifiedTopology: true });
mongoose.connection.on('error', console.error.bind(console, 'MongoDB connection error:'));

// Generate a secure random string to use as a session secret
const sessionSecret = crypto.randomBytes(64).toString('hex');

// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(session({
  secret: sessionSecret,
  resave: false,
  saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

// Passport Configuration
passport.use(new LocalStrategy({ usernameField: 'email' }, async (email, password, done) => {
  try {
    const user = await User.findOne({ email });
    if (!user) {
      return done(null, false, { message: 'User not found.' });
    }
    const match = await bcrypt.compare(password, user.password);
    if (!match) {
      return done(null, false, { message: 'Incorrect password.' });
    }
    return done(null, user);
  } catch (err) {
    return done(err);
  }
}));

passport.serializeUser((user, done) => {
  done(null, user.id);
});

passport.deserializeUser(async (id, done) => {
  try {
    const user = await User.findById(id);
    done(null, user);
  } catch (err) {
    done(err);
  }
});

// Serve static files from the public directory
app.use(express.static(path.join(__dirname, 'public')));

// Routes
app.use('/auth', authRoutes);

// Define route for the login page
app.get('/login', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'login.html'));
});

// Define route for the register page
app.get('/register', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'register.html'));
});

// Define route for user login
app.post('/login', async (req, res) => {
  const { email, password } = req.body;
  try {
    const user = await User.findOne({ email });
    if (!user) {
      console.log('User not found:', email);
      return res.status(400).json({ message: 'User not found.' });
    }
    console.log('Stored Password:', user.password);
    console.log('Provided Password:', password);
    const match = await bcrypt.compare(password, user.password);
    console.log('Password Match:', match);
    if (!match) {
      return res.status(400).json({ message: 'Incorrect password.' });
    }
    // Redirect to homepage after successful login
    res.redirect('/');
  } catch (error) {
    console.error('Error during login:', error);
    res.status(500).json({ message: 'Internal Server Error' });
  }
});

// Define route for the root path
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// Start the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

已尝试的方案

  • 尝试过MongoDB多集合合并、关联的相关方法
  • 尝试过使用视图关联两个集合的方案

需求

通过外键关联users与quizresults集合,实现登录用户提交测验后,成绩成功存入quizresults集合。

内容的提问来源于stack exchange,提问作者Sachin Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:33:24