5

我已经和 Sails 一起玩了一天。我正试图围绕在 Sails.js 中进行广泛验证的最佳方式来思考。

这是场景:

Registration Form:

Username: _______________
E-Mail:   _______________
Password: _______________
Confirm:  _______________

用户输入:

  • 正确的电子邮件
  • 已经存在的用户名
  • 两个不匹配的密码

期望的结果:

Username: _______________ x Already taken
E-Mail:   _______________ ✓
Password: _______________ ✓
Confirm:  _______________ x Does not match

要求,几个关键点:

  • 用户收到他输入的各个方面的所有错误消息(不仅仅是第一个错误消息) 。它们并不模糊(“用户名已被占用”或“用户名必须至少有 4 个字母长”比“无效用户名”更好)
  • 内置的模型验证显然不能负责检查匹配的密码确认(SRP)

我认为我需要做的:

用户控制器:

create: function(req, res) {
    try {
        // use a UserManager-Service to keep the controller nice and thin
        UserManager.create(req.params.all(), function(user) {
            res.send(user.toJSON());
        });
    }
    catch (e) {
        res.send(e);
    }
}

用户管理器:

create: function(input, cb) {
    UserValidator.validate(input); // this can throw a ValidationException which will then be handled by the controller
    User.create(input, cb); // this line should only be reached if the UserValidator did not throw an exception
}

用户:(型号)

attributes: {
    username: {
        type: 'string',
        required: true,
        minLength: 3,
        unique: true
    },

    email: {
        type: 'email',
        required: true,
        unique: true
    },

    password: {
        type: 'string',
        required: true
    }
}

用户验证器:

这是棘手的部分。我需要将特定于输入的验证(密码确认是否匹配?)与模型验证(用户名是否被采用,电子邮件地址是否有效?)结合起来。

如果有办法实例化用户模型并执行验证而不保存到 Sails/Waterline 中的数据库,我认为这将非常简单,但似乎没有那个选项。

你将如何解决这个问题?非常感谢您的帮助!

4

2 回答 2

8

您可以在模型中执行此操作:

module.exports = {
types: {
    mycustomtype: function (password) {
        return password === this.confirm;
    }
},
attributes: {,
    password:{
        type: 'STRING',
        required: true,
        mycustomtype: true
    }
}
}
于 2014-03-05T20:20:49.917 回答
3

您可以在客户端立即执行一些验证,而无需往返服务器。诸如比较密码和确认密码之类的事情,以及验证字符串是否匹配电子邮件正则表达式,都可以使用客户端 javascript 来完成。

对于检查用户名是否存在等其他事情,您可以使用 ajax 调用sails 直接询问“此用户名是否存在”并根据结果在客户端提供实时验证,或者您可以等待直到用户提交表单并解析表单提交以显示这些验证。由于提前检查此类事情并非 100% 可靠(即有人可以在检查后但在回发表单之前创建具有该名称的用户),因此有些人选择放弃预检查并仅处理发布后的错误。

Waterline 有自己的内置验证机制,称为Anchor,它建立在validator.js(以前称为 node-validator)之上。有关可用验证的完整列表,请参见此处我建议不要定义单独的验证层,而是定义一个方法来解析sails 验证消息并以用户友好和一致的方式对其进行格式化。

如果您想在 Waterline 为您执行的操作之外执行自己的验证,您可以在生命周期回调中执行这些验证,例如beforeCreate(values, callback)生命周期回调。如果您检测到错误,您可以将它们作为第一个参数传递给回调,并将它们作为错误传递回创建集合方法的调用者。

使用生命周期回调的替代方法是创建您自己的处理创建的集合方法。像这样的东西:

Users.validateAndCreate(req.params.all(), function (err, user) {
    ...
});

关于如何创建这样的收集方法的更多信息可以在我对这个问题的回答中找到:我如何编写sails函数以在控制器中使用?

于 2014-02-24T19:34:26.223 回答