使用Mongoose验证电子邮件唯一性的正确方法是什么?

v7pvogib  于 2022-09-18  发布在  Go
关注(0)|答案(3)|浏览(181)

我找不到一种适当的方法来验证Mongoose中的电子邮件唯一性。我没有发现任何实际有效的方法。我正在考虑使用Schema.pre,但如果是这样的话,我该如何编写代码呢?Mongoose的文档非常糟糕,没有描述PRE是如何做的或做了什么。

如果有人能告诉我这通常是怎么做的,或者给我指明正确的方向,我将不胜感激。我不明白为什么这么简单的东西在 Mongoose 身上就没有简单的解决方案。

pgccezyw

pgccezyw1#

我更喜欢在注册路线中检查电子邮件的唯一性。

这样,我们就可以完全控制应该向客户端发送哪些状态代码或错误消息。

router.post("/register", async (req, res) => {
  try {
    const { email, password } = req.body;

    let user = await User.findOne({ email });
    if (user) return res.status(400).send("User already registered.");

    user = new User({ email, password });
    user.password = await bcrypt.hash(user.password, 10);
    await user.save();

    res.send("registered");
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong");
  }
});
2vuwiymt

2vuwiymt2#

您可以使用自定义验证器:

var userSchema = new Schema({
  email: {
    type: String,
    validate: {
      validator: async function(email) {
        const user = await this.constructor.findOne({ email });
        if(user) {
          if(this.id === user.id) {
            return true;
          }
          return false;
        }
        return true;
      },
      message: props => 'The specified email address is already in use.'
    },
    required: [true, 'User email required']
  }
  // ...
});
jum4pzuy

jum4pzuy3#

多自定义验证

要对电子邮件字段运行多个验证检查,您需要为每个验证抛出具有不同消息的错误对象。

在本例中,我指定了3种不同的验证检查,包括唯一性,以及3种不同的自定义错误消息,但您可以根据需要添加任意多的检查。

const UserSchema = new Schema({
  email: {
    type: String,
    required: [true, "An email address is required."],
    validate: validateEmail,
  },
})

async function validateEmail(email) {
  if (!isEmail(email)) throw new Error("Please enter a valid email address.")
  const user = await this.constructor.findOne({ email })
  if (user) throw new Error("A user is already registered with this email address.")
}

首先,运行required检查,如果为空,则返回第一条验证消息。

其次,将函数传递给validate字段。在此函数中,email作为参数传递。isEmail可以是检查字符串是否为正确的电子邮件格式的任何类型的函数。如果失败,则使用新的错误对象指定错误消息

要使用Mongoose验证唯一性,请从answer above运行findOne查询,如果返回用户,则使用该验证文本抛出错误。

备注

  • 不需要从这些函数返回truefalse。如果验证失败,只需抛出错误,让函数自然解析即可。
  • 不要尝试将箭头函数传递给validate属性,这一点很重要,因为您需要在函数执行中提供词法作用域范围的this
  • 上面的答案是正确的,但不能解决除了Required和Unique之外还需要运行额外检查的问题,并为每个检查发送自定义错误消息。

相关问题