(Proudly powered by QKQ)
最近有個項目,其采用了前后端分離策略外莲,架構師提出:僅在前端作驗證猪半,后端不作驗證,認為傳入的數(shù)據(jù)是已經(jīng)在前端經(jīng)過了充分驗證了的偷线。提出這個的原因是該系統(tǒng)為內(nèi)部系統(tǒng)办龄,僅有內(nèi)部人員使用,如果出現(xiàn)有人繞過前端淋昭,直接訪問后端的情況,可以做事后處理和追溯安接。
那么翔忽,針對普通的項目,應當如何處理前端驗證和后端驗證呢盏檐?
Q: 這里的驗證的場景是什么歇式?
A: 比如說,用戶注冊胡野。用戶需要填寫一個表單材失,輸入諸如用戶名、密碼硫豆、郵箱龙巨、公司等信息笼呆,點擊提交,完成注冊旨别。
其中诗赌,這個表單需要驗證,可能的驗證規(guī)則有:
- 用戶名不能有特殊字符秸弛,如%¥#@&
- 郵箱必須符合正確的郵箱格式铭若,如koly@123.com
- 用戶名不能重復
- 密碼必須包含數(shù)字、小寫字母递览、大寫字母叼屠、特殊字符,且長度不能少于8位
Q: 前端驗證和后端驗證都是必須的嗎绞铃?
A: 從必要的角度來說镜雨,前端可以不做驗證,但是后端的驗證是必須做的憎兽。
為什么呢冷离?
前端不做驗證,但是在表單提交的時候纯命,后端驗證的結果會返回前端西剥,前端需要解析結果,顯示對應的內(nèi)容亿汞。對于驗證不通過的情況瞭空,需要展示相應的不通過的原因。
后端驗證一定要有疗我,是因為后端才是接收數(shù)據(jù)咆畏,并對數(shù)據(jù)進行操作和存儲的。只要保證了接收到的數(shù)據(jù)有足夠的驗證吴裤,就能保證最終存儲的數(shù)據(jù)是滿足了業(yè)務驗證條件的旧找,不是“臟數(shù)據(jù)”。
如果僅有前端驗證麦牺,沒有后端驗證钮蛛。在前后端分離的情況下,用戶可以繞過前端剖膳,直接訪問后端接口魏颓。那么前端驗證也就失效了。也就等于沒有對數(shù)據(jù)的業(yè)務驗證了吱晒。
同時甸饱,如果僅有前端驗證,部分驗證功能不好滿足。比如判斷數(shù)據(jù)庫是否存在相同的用戶名叹话,此時需要查詢數(shù)據(jù)庫才能判斷偷遗。如果前端不同后端交互,那么是不清楚用戶名是否重復的渣刷。
K: 后端有鹦肿,前端可無
Q: 前端驗證和后端驗證都是對同一個數(shù)據(jù)的驗證,有什么區(qū)別辅柴?
A: 二者的目的不同:
- 前端驗證是為了提供更好的用戶體驗箩溃;
- 后端驗證是為了保證數(shù)據(jù)滿足業(yè)務條件(business invariants);
有了不同的目的碌嘀,我們在設計前端驗證的時候涣旨,其出發(fā)點是更好的用戶體驗,即更好地引導客戶舒適地完成表單的正確填寫股冗。比如針對密碼設置霹陡,使用提示信息分行列出密碼的規(guī)則,當密碼輸入完畢之后止状,實時檢驗驗證規(guī)則是否滿足烹棉,對于滿足的規(guī)則,展示為綠色怯疤,并在規(guī)則前打勾浆洗,不滿足的規(guī)則展示為灰色,并在規(guī)則前打叉集峦。
K: 前端體驗伏社,后端保證
Q: 為什么一般都是前端驗證和后端驗證同時存在?
A: 綜合上述兩個問題的答案:
- 后端驗證必須存在
- 前端是為了更好的用戶體驗
所以塔淤,追求用戶體驗的情況下摘昌,二者都是需要的。
Q: 后端驗證就是數(shù)據(jù)庫限制么高蜂?
A: 不是聪黎。數(shù)據(jù)庫限制僅是數(shù)據(jù)上的一些約束,比如一個表里面的varchar長度最大為40备恤。
除了數(shù)據(jù)庫限制之外稿饰,還有業(yè)務限制。比如這個varchar的具體內(nèi)容應該滿足什么樣的格式烘跺。以上述的注冊表單為例,可能使用varchar(256)作為存儲郵件脂崔,但是數(shù)據(jù)庫并不會驗證其值為正確的郵箱格式滤淳。
K: 業(yè)務限制,數(shù)據(jù)限制(constraints)
參考資料:
[1] https://stackoverflow.com/questions/17039934/is-it-practical-to-have-back-end-database-side-validation-for-everything
[2] https://stackoverflow.com/questions/162159/javascript-client-side-vs-server-side-validation
[3] https://www.quora.com/Should-I-do-input-validation-on-the-front-end-or-back-end