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

如何在Mongoose中连接多集合?搭建用户认证系统的指引

实现用户数据存入users集合及搭建用户认证系统

一、将用户数据存入users集合

1. 编写注册路由与控制器逻辑

假设基于Express框架开发,先在路由文件中定义注册接口:

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

router.post('/register', authController.registerUser);

module.exports = router;

接着在控制器中实现用户保存逻辑,必须先加密密码(禁止存储明文):

// controllers/authController.js
const User = require('../models/User');
const bcrypt = require('bcrypt'); // 需提前安装:npm install bcrypt

exports.registerUser = async (req, res) => {
  try {
    const { username, email, password } = req.body;

    // 检查用户是否已存在
    const existingUser = await User.findOne({ email });
    if (existingUser) {
      return res.status(400).json({ message: '邮箱已被注册' });
    }

    // 加密密码
    const saltRounds = 10;
    const hashedPassword = await bcrypt.hash(password, saltRounds);

    // 创建新用户并写入users集合
    const newUser = new User({
      username,
      email,
      password: hashedPassword
    });

    await newUser.save();
    res.status(201).json({ 
      message: '用户注册成功', 
      user: { id: newUser._id, username, email } 
    });
  } catch (err) {
    res.status(500).json({ message: '服务器错误', error: err.message });
  }
};

2. 确认模型与集合映射

确保User模型已正确关联users集合(Mongoose默认会将模型名转为复数作为集合名,User对应users,也可显式指定):

// models/User.js
const mongoose = require('mongoose');

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

// 显式指定集合名(可选,默认即为users)
module.exports = mongoose.model('User', userSchema, 'users');

二、搭建用户认证系统的步骤与建议

1. 准备核心依赖

安装必要工具包:

npm install bcrypt jsonwebtoken express-jwt
  • bcrypt:负责密码加密与验证
  • jsonwebtoken:生成JWT身份令牌
  • express-jwt:简化JWT验证的中间件

2. 实现登录验证逻辑

在authController.js中添加登录方法:

const jwt = require('jsonwebtoken');
// 建议将密钥存入环境变量,避免硬编码
const JWT_SECRET = process.env.JWT_SECRET || 'your-private-secret-key';

exports.loginUser = async (req, res) => {
  try {
    const { email, password } = req.body;

    // 查找用户
    const user = await User.findOne({ email });
    if (!user) {
      return res.status(400).json({ message: '邮箱或密码错误' });
    }

    // 验证密码
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      return res.status(400).json({ message: '邮箱或密码错误' });
    }

    // 生成JWT令牌
    const token = jwt.sign(
      { id: user._id, email: user.email },
      JWT_SECRET,
      { expiresIn: '1h' } // 令牌有效期,可按需调整
    );

    res.status(200).json({ message: '登录成功', token });
  } catch (err) {
    res.status(500).json({ message: '服务器错误', error: err.message });
  }
};

在路由文件中添加登录接口:

// routes/auth.js
router.post('/login', authController.loginUser);

3. 保护需要认证的路由

创建JWT验证中间件,用于拦截未授权请求:

// middleware/authMiddleware.js
const { expressjwt: jwt } = require('express-jwt');
const JWT_SECRET = process.env.JWT_SECRET || 'your-private-secret-key';

exports.protect = jwt({
  secret: JWT_SECRET,
  algorithms: ['HS256'],
  requestProperty: 'user' // 验证通过后,用户信息会挂载到req.user上
});

在需要权限的路由中使用该中间件,比如书籍管理接口:

// routes/books.js
const express = require('express');
const router = express.Router();
const bookController = require('../controllers/bookController');
const { protect } = require('../middleware/authMiddleware');

// 仅登录用户可添加书籍
router.post('/', protect, bookController.createBook);

module.exports = router;

4. 可选优化方向

  • 环境变量管理:用dotenv包加载.env文件,存储JWT密钥、数据库连接字符串等敏感信息
  • 刷新令牌机制:实现令牌过期后免登录刷新,将刷新令牌存入数据库或HTTP-only Cookie
  • 输入校验:用joi或express-validator对注册/登录参数做合法性校验,避免脏数据入库
  • 角色权限控制:在User模型中添加role字段(如admin/user),扩展中间件实现细粒度权限校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:47:25