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
相关产品推荐
相关产品推荐

