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

Express用户/管理员注册登录API报错‘firstName未定义’排查及方向指引

问题描述

使用Express构建用户及管理员注册登录API时,Postman测试提交firstName等字段后,始终返回错误:firstName is not defined,附带相关代码文件,同时希望获得构建此类API的清晰方向。


错误原因排查

  • 静态方法参数缺失:user.model中的signup和login静态方法仅接收email和password,但验证逻辑里引用了未传入的firstName、lastName,导致变量未定义错误。
  • Controller层未传递必要字段:controller的signupUser和loginUser函数仅从req.body解构email和password,未获取firstName、lastName并传递给模型方法。
  • 哈希值赋值错误:signup方法创建用户时写了password: bcrypt.hash,实际应使用生成的哈希变量hash,而非bcrypt的方法本身。
  • Login逻辑冗余验证:登录无需验证firstName和lastName,仅需校验邮箱和密码。
  • Token函数无返回值:createToken调用jwt.sign但未返回生成的token,导致后续token变量为undefined。
  • 重复响应问题:loginUser和signupUser在try/catch后仍有res.json语句,会触发重复发送响应的错误。

修正后的关键代码

1. user.model.js 修正

const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const validator = require("validator");

const userSchema = new mongoose.Schema(
  {
    firstName: {
      type: String,
      required: true,
      trim: true,
    },
    lastName: {
      type: String,
      required: true,
      trim: true,
    },
    email: {
      type: String,
      required: true,
      trim: true,
      unique: true,
    },
    password: {
      type: String,
      required: true,
    },
    role: {
      type: String,
      enum: ["user", "admin"],
      default: "user",
    },
    contactNumber: { type: String },
    profilePicture: { type: String },
  },
  { timestamps: true }
);

// static signup method
userSchema.statics.signup = async function (firstName, lastName, email, password) {
  // validation
  if (!firstName || !lastName || !email || !password) {
    throw Error("All fields must be filled");
  }
  if (!validator.isEmail(email)) {
    throw Error("Email is not valid");
  }
  if (!validator.isStrongPassword(password)) {
    throw Error("Password is not strong enough");
  }

  const exists = await this.findOne({ email });
  if (exists) {
    throw Error("Email already in use");
  }
  const salt = await bcrypt.genSalt(10);
  const hash = await bcrypt.hash(password, salt);
  const user = await this.create({ firstName, lastName, email, password: hash });
  return user;
};

// static login method
userSchema.statics.login = async function (email, password) {
  if (!email || !password) {
    throw Error("All fields must be filled");
  }

  const user = await this.findOne({ email });
  if (!user) {
    throw Error("Incorrect Email");
  }

  const match = await bcrypt.compare(password, user.password);

  if (!match) {
    throw Error("Incorrect password");
  }

  return user;
};

module.exports = mongoose.model("User", userSchema);

2. controller/auth.js 修正

const User = require("../models/user");
const jwt = require("jsonwebtoken");

const createToken = (_id) => {
  return jwt.sign({ _id }, process.env.JWT_SECRET, { expiresIn: "3d" });
};

// login user
const loginUser = async (req, res) => {
  const { email, password } = req.body;
  try {
    const user = await User.login(email, password);
    const token = createToken(user._id);
    res.status(200).json({ email, token });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

// signup user
const signupUser = async (req, res) => {
  const { firstName, lastName, email, password } = req.body;
  try {
    const user = await User.signup(firstName, lastName, email, password);
    const token = createToken(user._id);
    res.status(200).json({ email, token });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

module.exports = { signupUser, loginUser };

Express构建Auth API的清晰方向

1. 分层结构规范

  • 路由层:仅定义API端点和对应处理函数,不包含业务逻辑
  • 控制器层:处理请求参数、调用模型方法、返回响应
  • 模型层:处理数据库操作、数据验证、加密等核心业务逻辑

2. 核心功能实现步骤

  1. 数据模型设计:用Mongoose定义用户Schema,添加字段验证规则
  2. 密码加密:注册时用bcrypt哈希密码,登录时对比哈希值
  3. JWT生成与验证:登录/注册成功后生成JWT,后续接口通过中间件验证JWT合法性
  4. 数据验证:可使用validator做基础验证,或用Zod/Joi实现更复杂的参数校验
  5. 错误处理:统一捕获并返回结构化错误信息,避免程序崩溃

3. 可选优化点

  • 添加JWT验证中间件,保护需要权限的接口
  • 实现密码重置功能
  • 完善用户角色权限控制
  • 用环境变量管理敏感配置(JWT密钥、数据库地址等)
  • 改用Zod做参数验证,获得更强大的类型校验和友好错误提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 11:24:16