Node.js 我们如何将参数传递给自定义express验证器?

Node.js 我们如何将参数传递给自定义express验证器?,node.js,express-validator,Node.js,Express Validator,我想阻止使用已经存在的电子邮件地址注册。是否可以使用ExpressValidator的新语法进行此操作?例如: router.post('/register', [ check('email').custom((value, {req}) => { return new Promise((resolve, reject) => { Users.findOne({email:req.body.email}, function(err,

我想阻止使用已经存在的电子邮件地址注册。是否可以使用ExpressValidator的新语法进行此操作?例如:

  router.post('/register', [
    check('email').custom((value, {req}) => {
        return new Promise((resolve, reject) => {
           Users.findOne({email:req.body.email}, function(err, user){
           if(err) {
             reject(new Error('Server Error'))
           }
           if(Boolean(user)) {
             reject(new Error('E-mail already in use'))
           }
           resolve(true)
         });
    });
  })
]
....

如何传递用户

将我的评论转化为最终的结论性答案:

验证器只是根据给定的数据类型/长度/模式标准来验证请求实体的字段


您需要自己编写该方法,以确定用户是否预先存在。如果项目存在于您的项目列表(或数据源)中,express验证器(或者更确切地说是任何验证器)都不会执行挑选任务,也不应该与相关数据源交互

将我的评论转化为最终的结论性答案:

验证器只是根据给定的数据类型/长度/模式标准来验证请求实体的字段


您需要自己编写该方法,以确定用户是否预先存在。如果项目存在于您的项目列表(或数据源)中,express验证器(或者更确切地说是任何验证器)都不会执行挑选任务,也不应该与相关数据源交互

express validator只知道请求对象本身,这使得它的复杂性对于最终用户来说非常低。
更重要的是,它只真正了解请求的输入位置--
正文
cookie
标题
查询
参数

您的自定义验证器是完全正确的。尽管如此,它可能不可测试,因为您似乎取决于全球环境

为了使其可测试,我看到的两个选项是:

1.注入请求用户: 这将涉及使用一些中间件将存储对象设置到
req

// Validator definition
const emailValidator = (value, { req }) => {
  return req.Users.findOne({ email: value }).then(...);
}

// In production code
// Sets req.Users, req.ToDo, req.YourOtherBusinessNeed
app.use(myObjectsStore.middleware);
app.post('/users', check('email').custom(emailValidator));

// In tests
req = { Users: MockedUsersObject };
expect(emailValidator('foo@bar.com', { req })).rejects.toThrow('email exists');
2.编写一个返回验证器实例的工厂函数: 这是我首选的解决方案,因为它不再涉及使用请求对象

// Validator definition
const createEmailValidator = Users => value => {
  return Users.findOne({ email: value }).then(...);
};

// In production code
app.post('/users', [
  check('email').custom(createEmailValidator(myObjectsStore.Users)),
]);

// Or in tests
expect(createEmailValidator(MockedUsersObject)('foo@bar.com')).rejects.toThrow('email exists');


希望这有帮助

express validator只知道请求对象本身,这使得它的复杂性对于最终用户来说非常低。
更重要的是,它只真正了解请求的输入位置--
正文
cookie
标题
查询
参数

您的自定义验证器是完全正确的。尽管如此,它可能不可测试,因为您似乎取决于全球环境

为了使其可测试,我看到的两个选项是:

1.注入请求用户: 这将涉及使用一些中间件将存储对象设置到
req

// Validator definition
const emailValidator = (value, { req }) => {
  return req.Users.findOne({ email: value }).then(...);
}

// In production code
// Sets req.Users, req.ToDo, req.YourOtherBusinessNeed
app.use(myObjectsStore.middleware);
app.post('/users', check('email').custom(emailValidator));

// In tests
req = { Users: MockedUsersObject };
expect(emailValidator('foo@bar.com', { req })).rejects.toThrow('email exists');
2.编写一个返回验证器实例的工厂函数: 这是我首选的解决方案,因为它不再涉及使用请求对象

// Validator definition
const createEmailValidator = Users => value => {
  return Users.findOne({ email: value }).then(...);
};

// In production code
app.post('/users', [
  check('email').custom(createEmailValidator(myObjectsStore.Users)),
]);

// Or in tests
expect(createEmailValidator(MockedUsersObject)('foo@bar.com')).rejects.toThrow('email exists');


希望这有帮助

我假设
用户
是猫鼬模式。没有必要将mongoose模式传递给ExpressValidator——我相信您更希望传递相同的请求主体字段。不,express validator与从数据库中获取值并检查用户是否存在不同-它只能检查请求正文中数据字段的约束,而不能检查它们在数据库中存储的实际值..没有人提到数据库,例如,用户可以是对象列表。我想我必须在实际的post请求函数中使用“check”,对吗?正如我所说的,考虑到express的上下文,我从您共享的代码中“推测”。但是,是的,你猜对了——你必须自己编写这个方法。如果项目存在于您的项目列表中,则
快速验证器(或者更确切地说,任何验证器)都不会执行挑选任务,也不应与项目列表交互。验证器只是根据给定的数据类型/长度/模式标准来验证请求实体的字段。我假设
用户
是mongoose模式。没有必要将mongoose模式传递给ExpressValidator——我相信您更希望传递相同的请求主体字段。不,express validator与从数据库中获取值并检查用户是否存在不同-它只能检查请求正文中数据字段的约束,而不能检查它们在数据库中存储的实际值..没有人提到数据库,例如,用户可以是对象列表。我想我必须在实际的post请求函数中使用“check”,对吗?正如我所说的,考虑到express的上下文,我从您共享的代码中“推测”。但是,是的,你猜对了——你必须自己编写这个方法。如果项目存在于您的项目列表中,则
快速验证器(或者更确切地说,任何验证器)都不会执行挑选任务,也不应与项目列表交互。验证器只是根据给定的数据类型/长度/模式标准来验证请求实体的字段。