如何在注册控制器中添加邮箱已存在的校验逻辑?
Got it, let's fix this for you. The core issue here is figuring out the right order to slot in that email-duplicate check—you want to run it before creating the user, and ideally after you've validated the email format (no point checking the database for an invalid email) but before hashing the password (no need to waste resources hashing if the email is already taken).
Also, a quick note: your original code uses User.find({ email }) which returns an array (even if only one user matches). You'll want to use User.findOne({ email }) instead—it returns either the matching user document or null, making the existence check way cleaner.
Here's the revised version of your controller with the email check added in the correct spot, plus explanations of the order:
module.exports = { registerUser: async(req, res, next) => { try { var { username, email, password } = req.body // 1. First, make sure all required fields are present if (!username || !email || !password) { return res .status(400) .json({ message: "Username, email and password are must" }) } // 2. Validate email format before checking the database if (!validator.isEmail(email)) { return res.status(400).json({ message: "Invalid email" }) } // 3. Check if password meets length requirements if (password.length < 6) { return res .status(400) .json({ message: "Password should be of at least 6 characters" }) } // 4. NOW check if the email already exists in the database const existingUser = await User.findOne({ email }) if (existingUser) { return res.status(400).json({ message: "User with this email already exists" }) } // 5. Only hash the password if all checks pass (no wasted computation) const salt = bcrypt.genSaltSync(10) password = bcrypt.hashSync(password, salt) // 6. Finally, create the new user const user = await User.create({ username, email, password }) if (!user) { return res.status(404).json({ error: "Failed to create user" }) } return res.status(200).json({ user }) } catch (error) { return next(error) } } }
Why this order works:
- We start with basic required field checks to fail fast—no need to do any extra work if the user didn't fill in mandatory info.
- Validating the email format first means we don't query the database for an invalid email address (which would be a waste of resources).
- Checking for existing emails before hashing the password saves us from running the bcrypt hashing process if the registration is going to fail anyway.
- Using
findOneinstead offindgives us a directnull/document result, so theif (existingUser)check works as expected.
内容的提问来源于stack exchange,提问作者user13496554

