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

Express JWT认证注册时Mongoose报password必填验证错误

问题:Mongoose抛出"Path password is required"验证错误但控制台能打印password值

我用Express实现基于refresh token和access token的认证功能,Postman调用注册接口后,控制台能正常打印password值,但Mongoose抛出“Path password is required”的ValidatorError验证错误。

用户控制器代码

class UserController {
  async registration(req, res, next) {
    try {
      const { email, password } = req.body;
      console.log("pass from user controller " + password);
      const userData = await userService.registration(email, password);
      res.cookie("refreshtoken", userData.refreshToken, {
        maxAge: 30 * 24 * 60 * 60 * 1000,
        httpOnly: true,
      });
      return res.json(userData);
    } catch (error) {
      console.log(error);
    }
  }
}

用户模型代码

import mongoose from "mongoose";
const UserSchema = new mongoose.Schema({
  email: {
    type: String,
    unique: true,
    required: true,
  },
  password: {
    type: String,
    required: true,
  },
  isActivated: { type: Boolean, default: false },
  activationLink: { type: String },
});
export default mongoose.model("User", UserSchema);

用户服务代码

import UserModel from "../models/user-model.js";
import bcrypt from "bcrypt";
import { v4 as uuid } from "uuid";
import mailService from "./mail-service.js";
import tokenService from "./token-service.js";
import UserDto from "../dtos/user-dto.js";
class UserService {
  async registration(email, password) {
    const candidate = await UserModel.findOne({ email });
    console.log("pass form user Service " + password);
    if (candidate) {
      throw new Error(`Usser with this email ${email} already exists`);
    }
    const hashPassword = await bcrypt.hash(password, 3);
    const activationLink = uuid();
    const user = await UserModel.create({
      email,
      hashPassword,
      activationLink,
    });
    await mailService.sendActicvationMail(email, activationLink);
    const userDto = new UserDto(user);
    const tokens = tokenService.generateToken({ ...userDto });
    await tokenService.saveToken(userDto.id, tokens.refreshToken);
    return {
      ...tokens,
      user: userDto,
    };
  }
}
export default new UserService();

完整错误信息

errors: {
password: ValidatorError: Path `password` is required.
at validate (/home/galich/Desktop/backend/jwt-authorization/server/node_modules/mongoose/lib/schematype.js:1337:13)
at SchemaString.SchemaType.doValidate (/home/galich/Desktop/backend/jwt-authorization/server/node_modules/mongoose/lib/schematype.js:1321:7)
at /home/galich/Desktop/backend/jwt-authorization/server/node_modules/mongoose/lib/document.js:2831:18
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
properties: [Object],
kind: 'required',
path: 'password',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'User validation failed'
}

排查与修复方案

核心问题是创建用户时传入的字段名与模型定义不匹配:

  • 模型里明确要求password字段为必填,但在UserService.registration方法中调用UserModel.create()时,传入的是hashPassword而非password,导致Mongoose校验时检测到password字段缺失,抛出必填错误。
  • 控制台能打印password是因为控制器和服务都正确获取到了请求中的password值,但存入数据库时未将哈希后的密码赋值给模型要求的字段。

修复步骤:
修改用户服务中创建用户的代码,将哈希后的密码赋值给password字段:

const user = await UserModel.create({
  email,
  password: hashPassword, // 替换原有的hashPassword字段
  activationLink,
});

(可选优化)为避免变量名混淆,可将哈希后的密码变量名改为hashedPassword,代码可读性更高:

const hashedPassword = await bcrypt.hash(password, 3);
// ...
const user = await UserModel.create({
  email,
  password: hashedPassword,
  activationLink,
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:24:16