2014-02-21 45 views
5

我一直在玩Sails可能有一天。我試圖圍繞什麼是Sails.js中進行廣泛驗證的最佳方式。Sails.js中的密碼確認和外部模型驗證

下面是這種情況:

Registration Form: 

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

用戶輸入:

  • 一個正確的電子郵件
  • 已經存在
  • 兩個密碼輸入用戶名,唐」 t match

期望的結果:

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

要求,有幾個關鍵點:

  • 用戶收到所有錯誤消息(不僅僅是第一個)爲方方面面他的輸入是。他們是不含糊(「用戶名已被佔用」或「用戶名必須至少4個字母長」比「無效用戶名」更好)
  • 內置的模型驗證顯然不會負責檢查匹配的密碼確認(SRP)

我想我需要做的:

UserController中:

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); 
    } 
} 

的UserManager:

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 
    } 
} 

UserValidator:

這是棘手的部分。我需要將輸入特定驗證(密碼確認匹配?)與模型驗證(使用的用戶名是否是電子郵件地址有效?)相結合。

如果有一種方法來實例化用戶模型並執行驗證而不保存到Sails/Waterline中的數據庫,我認爲這將是非常直接的,但似乎沒有這種選擇。

你將如何去解決這個問題?非常感謝您的幫助!

回答

3

您將可以立即在客戶端執行一些驗證,而無需往返於服務器。諸如將密碼與確認密碼進行比較以及驗證字符串是否與電子郵件正則表達式匹配可以使用客戶端JavaScript完成。

對於諸如檢查用戶名是否存在等其他事情,您可以使用ajax調用sails直接詢問它'是否存在此用戶名',並根據結果在客戶端提供實時驗證,或者您可以等到用戶提交表單並解析表單提交以顯示這些驗證。由於提前檢查這樣的事情不是100%可靠的(例如,在檢查之後但在表格被回傳之前有人可以創建一個具有該名字的用戶),所以一些人選擇放棄預檢並且只處理髮布後的錯誤。

水線有其自己的內置驗證機制,稱爲Anchor,它建立在validator.js(以前稱爲節點驗證器)上。有關可用驗證的完整列表,請參見here我建議您不要定義單獨的驗證圖層,而是定義一種方法來解析風帆驗證消息並以便於用戶使用和一致的方式對其進行格式化。

如果你想什麼水線願意爲你做外執行自己的驗證,你可以做這些驗證一個lifecycle callback裏面,比如beforeCreate(values, callback)生命週期回調。如果您檢測到錯誤,則可以將它們作爲第一個參數傳遞給回調函數,並將它們作爲錯誤傳遞給create collection方法的調用方。

使用生命週期回調的替代方法是創建自己的處理創建的集合方法。事情是這樣的:

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

有關如何創建一個收集方法這樣才能在我的答案中找到這個問題的更多信息:How can I write sails function on to use in Controller?

+0

嗨乍得,謝謝你幫助我!我可能對此有點挑剔,但對用戶來說,一些事情經過驗證客戶端和其他服務器必須等待來自服務器的響應,這一點對他們來說很奇怪。另一方面,我想你可能會爭辯說服務器不應該關心密碼匹配,因爲它幾乎只是一個UI的東西。但是當我必須引入模型無法完成的服務器端驗證時會發生什麼?如何在單個錯誤消息中將它與模型驗證結合起來?這實際上是我的問題的核心。再次感謝! :) – Macks

+0

您需要決定您希望您的客戶端驗證有多強大。你可以像挑剔一樣,它是你的應用程序:) 我添加了一些額外的細節,我的答案解決處理驗證以外的模型將提供。您可以在生命週期回調或自定義收集方法中執行跨模型驗證,api查詢等。這兩種解決方案之一很可能會滿足您的需求。 –

+0

嘿乍得,感謝您的快速反應!這些生命週期回調可能對我有用,我必須檢查它們。謝謝! – Macks

8

你可以在你的模型做這樣的:

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