博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
让 ASP.NET JS验证和服务端的 双验证 更简单
阅读量:7123 次
发布时间:2019-06-28

本文共 8080 字,大约阅读时间需要 26 分钟。

转自: http://www.cnblogs.com/sunkaixuan/p/4550580.html

只用JavaScript验证安全不安全 谁都知道,答案是不安全,非常的不安全。因为在客户端进行的验证相当于“让用户自己验证自己”,很明显是不靠谱的。你不能避免一些恶意用户人为的修改自己的表单进行欺骗,也不能避免第三方对表单进行截获后进行篡改再提交。 所以说,从安全的角度来说,单纯的依靠js验证,是不安全的,任何健壮的系统都必须在后端进行验证。 双验证大大增加了工作量,如何解决? 方案1:笨方法,都写一遍 方案2:现有框架 ,比如MVC自带验证支持双向验证 ,不足点是要写 model加attrbute 也要有一定工作量 方案3:自已封装 我的选择方案:方案3 思路 page 加载时通过Key去存储表 form规则,通过form规则生成前台元素的绑定,完成前台验证。后台函数通过key在获取表单规则进行后台验证。(可以用缓存机质提高性能) 实现 后台代码: 通过GetInitScript存储form规则并且赋值给 ViewState["intisript"]去前台绑定
前台调用只要绑定 viewState["intiscript"] (其实什么都不要写,保证元素name和 viewstate中一致就可以了):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<body>
    
<form id=
"form1" 
runat=
"server" 
class
=
"contact_form"
>
    
<ul>
        
<li>
            
<h2>
                
表单验证</h2>
            
<span 
class
=
"required_notification"
>* 表示必填项</span> </li>
        
<li>
            
<label 
for
=
"name"
>
                
姓名:</label>
            
<input type=
"text" 
name=
"name" 
/>
        
</li>
        
<li>
            
<label>
                
姓别:</label>
            
<input type=
"radio" 
value=
"1" 
name=
"sex" 
/>男
            
<input type=
"radio" 
value=
"0" 
name=
"sex" 
/>女 </li>
        
<li>
            
<label 
for
=
"email"
>
                
电子邮件:</label>
            
<input type=
"email" 
name=
"email" 
/>
        
</li>
        
<li>
            
<label 
for
=
"website"
>
                
手 机:</label>
            
<input type=
"text" 
name=
"phone" 
/>
        
</li>
        
<li>
            
<label 
for
=
"website"
>
                
学 历:</label>
            
<
select 
name=
"education" 
>
                
<option value=
""
>==请选择==</option>
                
<option value=
"1"
>大学</option>
            
</
select
>
        
</li>
        
<li>
            
<label 
for
=
"message"
>
                
备注:</label>
            
<textarea name=
"remark" 
cols=
"40" 
rows=
"6"
></textarea>
        
</li>
        
<li></li>
    
</ul>
    
<br />
    
<asp:Button ID=
"Button1" 
runat=
"server" 
Text=
"submit" 
CssClass=
"submit" 
OnClick=
"Button1_Click" 
/>
    
</form>
   
<span style=
"color: #ff0000;"
> <%=ViewState[
"intiscript"
]%></span>
</body>
 

  

ViewState["intiscript"] 将生成一段脚本 给HTML元素添加 pattern、placeholder和requierd 等属性 ,有了这些属性可以很方便的使用JS等插件进行前端验证 下面是通过ViewState["intiscript"] 生成出来的HTML
 
1
 
 
后台使用 PostValidation函数进行验证

我们来看看效果:

 

 

 

提交成功验证通过了,下面我来改下前端元素采 用恶意参数 提交后台

前台验证通过:

后台还是要把你给揪出来

最后附上C#验证类代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
using 
System;
using 
System.Collections.Generic;
using 
System.Linq;
using 
System.Text;
using 
System.Text.RegularExpressions;
 
 
/// <summary>
/// ** 描述:可以方便实现前后端双验证,基于jquery
/// ** 创始时间:2015-6-4
/// ** 修改时间:-
/// ** 作者:sunkaixuan
/// ** 使用说明:-
/// </summary>
public 
class 
ValidationSugar
{
 
    
private 
static 
List<ValidationOption> ValidationOptionList = 
new 
List<ValidationOption>();
 
    
/// <summary>
    
/// 前台注入
    
/// </summary>
    
/// <param name="pageKey"></param>
    
/// <param name="itemList"></param>
    
public 
static 
string 
GetInitScript(
string 
pageKey, List<OptionItem> itemList)
    
{
        
//初始化后不在赋值
        
if 
(ValidationOptionList.Any(it => it.PageKey == pageKey))
        
{
            
return 
(ValidationOptionList.Single(c => c.PageKey == pageKey).Script);
        
}
        
else
        
{
            
ValidationOption option = 
new 
ValidationOption();
            
string 
uk = Guid.NewGuid().ToString().Replace(
"-"
""
);
//唯一函数名
            
string 
script = 
@"<script>
var bindValidation{1}=function(name,params){
{
     
var selectorObj=$(""[name='""+name+""']"");
     
selectorObj.after(""<span class=\""form_hint\"">""+params.tip+""</span>"");
     
if(params.pattern!=null)
     
selectorObj.attr(""pattern"",params.pattern);
     
if(params.placeholder!=null)
     
selectorObj.attr(""placeholder"",params.placeholder);
     
if(params.isRequired=true)
     
selectorObj.attr(""required"",params.isRequired);
}}
 
 
 
{0}</script>"
;
            
StringBuilder itemsCode = 
new 
StringBuilder();
            
foreach 
(
var 
item 
in 
itemList)
            
{
                
switch 
(item.Type)
                
{
                    
case 
OptioItemType.Mail:
                        
item.Pattern = 
@"^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$"
;
                        
break
;
                    
case 
OptioItemType.Int:
                        
item.Pattern = 
@"^\\d{1,11}$"
;
                        
break
;
                    
case 
OptioItemType.Double:
                        
item.Pattern = 
@"^\\d{1,11}$"
;
                        
break
;
                    
case 
OptioItemType.IdCard:
                        
item.Pattern = 
@"^(\\d{15}$|^\\d{18}$|^\\d{17}(\\d|X|x))$"
;
                        
break
;
                    
case 
OptioItemType.Date:
                        
item.Pattern = 
@"^(((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/])(10|12|0?[13578])([-\\/])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/])(11|0?[469])([-\\/])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/])(0?2)([-\\/])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\\/])(0?2)([-\\/])(29)$)|(^([3579][26]00)([-\\/])(0?2)([-\\/])(29)$)|(^([1][89][0][48])([-\\/])(0?2)([-\\/])(29)$)|(^([2-9][0-9][0][48])([-\\/])(0?2)([-\\/])(29)$)|(^([1][89][2468][048])([-\\/])(0?2)([-\\/])(29)$)|(^([2-9][0-9][2468][048])([-\\/])(0?2)([-\\/])(29)$)|(^([1][89][13579][26])([-\\/])(0?2)([-\\/])(29)$)|(^([2-9][0-9][13579][26])([-\\/])(0?2)([-\\/])(29))|(((((0[13578])|([13578])|(1[02]))[\\-\\/\\s]?((0[1-9])|([1-9])|([1-2][0-9])|(3[01])))|((([469])|(11))[\\-\\/\\s]?((0[1-9])|([1-9])|([1-2][0-9])|(30)))|((02|2)[\\-\\/\\s]?((0[1-9])|([1-9])|([1-2][0-9]))))[\\-\\/\\s]?\\d{4})(\\s(((0[1-9])|([1-9])|(1[0-2]))\\:([0-5][0-9])((\\s)|(\\:([0-5][0-9])\\s))([AM|PM|am|pm]{2,2})))?$"
;
                        
break
;
                    
case 
OptioItemType.Mobile:
                        
item.Pattern = 
@"^[0-9]{11}$"
;
                        
break
;
                    
case 
OptioItemType.Telephone:
                        
item.Pattern = 
@"^(\\(\\d{3,4}\\)|\\d{3,4}-|\\s)?\\d{8}$"
;
                        
break
;
                    
case 
OptioItemType.Fax:
                        
item.Pattern = 
@"^[+]{0,1}(\\d){1,3}[ ]?([-]?((\\d)|[ ]){1,12})+$"
;
                        
break
;
                    
case 
OptioItemType.Regex:
                        
break
;
                
}
                
itemsCode.AppendFormat(
"bindValidation{0}('{1}',{
{   tip:'{2}',pattern:'{3}',placeholder:'{4}',isRequired:{5} }})"
, uk, item.FormFiledName, item.Tip, item.Pattern, item.Placeholder, item.IsRequired ? 
"true" 
"false"
);
                
itemsCode.AppendLine();
            
}
            
option.Script = 
string
.Format(script, itemsCode.ToString(), uk);
            
script = 
null
;
            
itemsCode.Clear();
            
option.PageKey = pageKey;
            
option.ItemList = itemList;
            
ValidationOptionList.Add(option);
            
return 
(option.Script);
        
}
    
}
 
    
/// <summary>
    
/// 后台验证
    
/// </summary>
    
/// <param name="pageKey"></param>
    
/// <param name="errorMessage">json格式</param>
    
/// <returns></returns>
    
public 
static 
bool 
PostValidation(
string 
pageKey, 
out 
string 
errorMessage)
    
{
        
bool 
isSuccess = 
true
;
        
errorMessage = 
string
.Empty;
        
if 
(!ValidationOptionList.Any(c => c.PageKey == pageKey))
        
{
            
throw 
new 
ArgumentNullException(
"ValidationSugar.PostValidation.pageKey"
);
        
}
        
var 
context = System.Web.HttpContext.Current;
        
var 
itemList = ValidationOptionList.Where(c => c.PageKey == pageKey).Single().ItemList;
        
var 
successItemList = itemList.Where(it => (it.IsRequired && !
string
.IsNullOrEmpty(context.Request[it.FormFiledName]) || !it.IsRequired)).Where(it => Regex.IsMatch(context.Request[it.FormFiledName], it.Pattern.Replace(
@"\\"
@"\"
))).ToList();
        
isSuccess = (successItemList.Count == itemList.Count);
        
if 
(!isSuccess)
        
{
            
errorMessage = 
new 
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(itemList);
        
}
        
return 
isSuccess;
    
}
 
 
    
private 
class 
ValidationOption
    
{
        
public 
string 
PageKey { 
get
set
; }
        
public 
string 
Script { 
get
set
; }
        
public 
List<OptionItem> ItemList { 
get
set
; }
 
    
}
 
    
public 
enum 
OptioItemType
    
{
        
Mail = 0,
        
Int = 2,
        
Double = 3,
        
IdCard = 4,
        
Date = 5,
        
/// <summary>
        
/// 移动电话
        
/// </summary>
        
Mobile = 6,
        
/// <summary>
        
/// 座机
        
/// </summary>
        
Telephone = 7,
        
Fax = 8,
        
/// <summary>
        
/// 没有合适的,请使用正则验证
        
/// </summary>
        
Regex = 1000
 
    
}
    
/// <summary>
    
/// 验证选项
    
/// </summary>
    
public 
class 
OptionItem
    
{
        
/// <summary>
        
/// 验证类型
        
/// </summary>
        
public 
OptioItemType Type { 
get
set
; }
        
/// <summary>
        
/// 正则
        
/// </summary>
        
public 
string 
Pattern { 
get
set
; }
        
/// <summary>
        
/// 是否必填
        
/// </summary>
        
public 
bool 
IsRequired { 
get
set
; }
        
/// <summary>
        
/// 表单字段名(name或者id)
        
/// </summary>
        
public 
string 
FormFiledName { 
get
set
; }
        
/// <summary>
        
/// 水印
        
/// </summary>
        
public 
string 
Placeholder { 
get
set
; }
        
/// <summary>
        
/// 提醒
        
/// </summary>
        
public 
string 
Tip { 
get
set
; }
 
    
}
}

  

源码下载:http://pan.baidu.com/s/1mgoXpsW 时间问题只支持HTML5验证,需要高版本浏览器,以后我会慢慢完善
你可能感兴趣的文章
除了BAT,国内还有哪些值得关注的人工智能公司?
查看>>
干货分享:app运营推广超实用计划书
查看>>
史上最全Python从入门到资深书籍资料分享!
查看>>
校园考勤管理系统
查看>>
向国外发送超大文件,用什么工具好?
查看>>
【JS教程】JS小功能代码片段(二)
查看>>
BugFree的7种解决方案各自的含义
查看>>
数据类型转换
查看>>
Vim简明教程
查看>>
C/C++程序调试和内存检测
查看>>
vlan 03
查看>>
从零撸起-微信小游戏-1,最基础的知识
查看>>
将Bitmap对象转化为图片文件File
查看>>
DEV报表注意事项(二)
查看>>
超实用的Linux/Unix快捷键大汇总
查看>>
流编辑器sed命令详解
查看>>
wps for linux 不能使用搜狗输入法
查看>>
PHP与MySQL学习笔记9:创建Web数据库
查看>>
useradd、adduser和userdel在使用时的注意事项
查看>>
替你写代码
查看>>