【问题标题】:Password confirmation and external Model validation in Sails.jsSails.js 中的密码确认和外部模型验证
【发布时间】:2014-03-23 01:12:36
【问题描述】:

我玩 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 中的数据库,我认为这将非常简单,但似乎没有那个选项。

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

【问题讨论】:

    标签: node.js validation orm sails.js waterline


    【解决方案1】:

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

    module.exports = {
    types: {
        mycustomtype: function (password) {
            return password === this.confirm;
        }
    },
    attributes: {,
        password:{
            type: 'STRING',
            required: true,
            mycustomtype: true
        }
    }
    }
    

    【讨论】:

      【解决方案2】:

      将有一些验证可以立即在客户端执行,而无需往返服务器。诸如将密码与确认密码进行比较以及验证字符串是否与电子邮件正则表达式匹配等事情都可以通过客户端 javascript 完成。

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

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

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

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

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

      关于如何创建这样的收集方法的更多信息可以在我对这个问题的回答中找到:How can I write sails function on to use in Controller?

      【讨论】:

      • 嗨,乍得,感谢您帮助我!我可能对此有点挑剔,但用户一定很奇怪,有些东西是在客户端验证的,而另一些东西必须等待来自服务器的响应。另一方面,我想你可能会争辩说服务器不应该关心密码匹配,因为它几乎只是一个 UI 的东西。但是当我必须引入模型无法完成的服务器端验证时会发生什么?如何在单个错误消息中将其与模型验证结合起来?这实际上是我问题的核心。再次感谢! :)
      • 由您决定您希望客户端验证的稳健程度。您可以随心所欲地挑剔,这是您的应用程序:) 我在我的答案中添加了一些额外的细节,以解决模型提供的处理验证之外的问题。您可以在生命周期回调或自定义集合方法中执行跨模型验证、api 查询等。这两种解决方案中的一种很可能满足您的需求。
      • 嘿乍得,感谢您的快速响应!这些生命周期回调可能对我有用,我必须检查它们。谢谢!
      猜你喜欢
      • 2013-09-18
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 2023-02-23
      • 1970-01-01
      • 2012-12-08
      • 2011-08-23
      相关资源
      最近更新 更多