转自: 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 { getset; }
        public string Script { getset; }
        public List<OptionItem> ItemList { getset; }
    }
    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 { getset; }
        /// <summary>
        /// 正则
        /// </summary>
        public string Pattern { getset; }
        /// <summary>
        /// 是否必填
        /// </summary>
        public bool IsRequired { getset; }
        /// <summary>
        /// 表单字段名(name或者id)
        /// </summary>
        public string FormFiledName { getset; }
        /// <summary>
        /// 水印
        /// </summary>
        public string Placeholder { getset; }
        /// <summary>
        /// 提醒
        /// </summary>
        public string Tip { getset; }
    }
}

  

源码下载:http://pan.baidu.com/s/1mgoXpsW

时间问题只支持HTML5验证,需要高版本浏览器,以后我会慢慢完善

让 ASP.NET JS验证和服务端的 双验证 更简单相关推荐

  1. 服务器客户端证书,客户端如何验证HTTPS服务端证书信息

    通过一个例子说明客户端如何验证HTTPS服务端的证书信息. 类型浏览器如何验证WEB服务器的证书信息. 生成服务器端证书,以及CA证书 # generate ca certificate $ open ...

  2. 《“透视”个人大数据》项目开发小记 --(二)网络服务端,邮箱验证和手机验证(C#,Java)

    现在网络的应用越来越普及,网络的构建也越来越简便,对于某些研究性项目自建网络服务端 也是可行的方案.本项目的网络服务,是用C#,基于Socket构建的,核心的工作是通过自定的BS60传输协议,实现与手 ...

  3. ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

    ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需要将相应的ValidationAttri ...

  4. 服务器端授权验证,移动应用的第三方平台登录在服务端的授权验证

    如今,很多移动应用在做用户注册/登录的时候,为减少用户的交互成本,会考虑引入常用的第三方平台的开放登录授权来快速的将用户倒流到自己的平台中.在原来的第三方登录中,很多是采用基于 Web 的 Oauth ...

  5. ajax向服务端发送请求验证用户名是否可用小示例

    使用ajax向服务器发送请求 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  6. js与C#服务端 json数据交互

    1.1 服务端返回给前端 返回的数据都放入对象中(根据需求:单个对象,集合,键值对),然后JSON序列化返回给前端.这里可以引用JSON.NET 库,也可以用.NET自带的类库: JavaScript ...

  7. 苹果支付成功后,JAVA服务端二次验证

    原理简述: 苹果客户端在完成应用购买,下单后支付,苹果后台会给客户端返回信息,用来验证支付结果: 客户端在拿到返回值后,将指定返回值,通过接口形式请求应用服务器,应用服务器根据这个值调用苹果服务器进行 ...

  8. nuxt.js之SSR服务端内存泄漏导致CPU过高的解决过程

    问题 最近在公司维护nuxt项目时,线上遇到了一个问题--访问网站,网站会报502或者JS.css资源报502. 去运维那一查pm2,项目node服务器的CPU达到了100%,实际上这段时间并没有人访 ...

  9. 用 next.js 做一个服务端渲染的加密货币网站

    学习 next.js next.js 是一个基于 React 的通用 JavaScript 框架,next.js 为 React 组件模型提供了扩展,支持基于服务器的组件渲染 (SSR),同时也支持在 ...

最新文章

  1. OpenCV——图像的平移旋转
  2. linux运维如何月薪过万?(收藏自用)
  3. RuntimeError: The current Numpy installation fails to pass a sanity check due to a bug in the window
  4. Amazon S3 功能介绍
  5. table { border-collapse:collapse; }
  6. CentOS 中 配置 Nginx 支持 https
  7. 无心剑中译丁尼生《磨坊主千金》
  8. 流量 起伏大_广西崇左的德天跨国大瀑布,一半是中国一半是越南,天下奇观!...
  9. 基于Spring Security的认证授权_自定义登录页面_Spring Security OAuth2.0认证授权---springcloud工作笔记127
  10. Zabbix 对接 LDAP 实现用户统一登录的方法
  11. POJ NOI MATH-7647 余数相同问题
  12. 达内CEO受邀出席搜狐“2011职业教育高峰论坛”
  13. ubuntu apt-get install更新域名解析失败问题的处理方法
  14. oracle中substr () in,Oracle中的substr()函数使用详解及应用
  15. 是不是不知道用什么命令查看mac系统信息?
  16. 自编码器(Auto-encoder)的概念和应用
  17. (二、八、十、十六)进制转换
  18. python 中m op n运算_nltk语言模型(ngram)计算上下文中单词的prob
  19. Linux系统下SoftEther的使用方法
  20. VC 出错 msdev.exe错误

热门文章

  1. 那个马斯克的小迷弟开始讲深度学习了,课程视频+PPT已放出
  2. 浅谈SnackBar(Toast大兄弟)
  3. 系统封装教程集合电子书
  4. 给模型添加ORM,与持久化记录
  5. 切实把握大数据时代的新机遇新变革
  6. 自适应滤波:维纳滤波器——FIR及IIR设计
  7. 如何“在21天内自学C++”
  8. 异常笔记:运行hdfs copyFromLocal 上传文件报错
  9. Nodejs中的this详解
  10. Hadoop学习笔记—14.ZooKeeper环境搭建