只用JavaScript验证安全不安全

谁都知道,答案是不安全,非常的不安全。因为在客户端进行的验证相当于“让用户自己验证自己”,很明显是不靠谱的。你不能避免一些恶意用户人为的修改自己的表单进行欺骗,也不能避免第三方对表单进行截获后进行篡改再提交。 所以说,从安全的角度来说,单纯的依靠js验证,是不安全的,任何健壮的系统都必须在后端进行验证。 双验证大大增加了工作量,如何解决? 方案1:笨方法,都写一遍

方案2:现有框架 ,比如MVC自带验证支持双向验证 ,不足点是要写 model加attrbute 也要有一定工作量 方案3:自已封装 我的选择方案:方案3 思路
page 加载时通过Key去存储表 form规则,通过form规则生成前台元素的绑定,完成前台验证。后台函数通过key在获取表单规则进行后台验证。(可以用缓存机质提高性能) 实现 后台代码: 通过GetInitScript存储form规则并且赋值给 ViewState["intisript"]去前台绑定 前台调用只要绑定 viewState["intiscript"] (其实什么都不要写,保证元素name和 viewstate中一致就可以了):
<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>
<%=ViewState["intiscript"]%>
</body>

  

 ViewState["intiscript"] 将生成一段脚本 给HTML元素添加 pattern、placeholder和requierd 等属性 ,有了这些属性可以很方便的使用JS等插件进行前端验证

下面是通过ViewState["intiscript"] 生成出来的HTML


 


后台使用 PostValidation函数进行验证


我们来看看效果:


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


前台验证通过:

后台还是要把你给揪出来

最后附上C#验证类代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions; namespace SyntacticSugar
{
/// <summary>
/// ** 描述:可以方便实现前后端双验证,基于jquery
/// ** 创始时间:2015-6-4
/// ** 修改时间:-
/// ** 作者:sunkaixuan
/// ** 使用说明:http://www.cnblogs.com/sunkaixuan/p/4550580.html
/// </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 OptionItemType.Mail:
item.Pattern = @"^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$";
break;
case OptionItemType.Int:
item.Pattern = @"^\\d{1,11}$";
break;
case OptionItemType.Double:
item.Pattern = @"^\\d{1,11}$";
break;
case OptionItemType.IdCard:
item.Pattern = @"^(\\d{15}$|^\\d{18}$|^\\d{17}(\\d|X|x))$";
break;
case OptionItemType.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 OptionItemType.Mobile:
item.Pattern = @"^[0-9]{11}$";
break;
case OptionItemType.Telephone:
item.Pattern = @"^(\\(\\d{3,4}\\)|\\d{3,4}-|\\s)?\\d{8}$";
break;
case OptionItemType.Fax:
item.Pattern = @"^[+]{0,1}(\\d){1,3}[ ]?([-]?((\\d)|[ ]){1,12})+$";
break;
case OptionItemType.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 OptionItemType
{
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 OptionItemType 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验证,需要高版本浏览器,以后我会慢慢完善

让 ASP.NET JS验证和服务端的 双验证 更简单的更多相关文章

  1. jQuery结合Ajax实现简单的前端验证和服务端查询

    上篇文章写了简单的前端验证由传统的JavaScript转向流畅的jQuery滑动验证,现在拓展一下,使用Ajax实现用户体验比较好的异步查询,同样还是从建立一个简单的表单开始 <form nam ...

  2. Pomelo:网易开源基于 Node.js 的游戏服务端框架

    Pomelo:网易开源基于 Node.js 的游戏服务端框架 https://github.com/NetEase/pomelo/wiki/Home-in-Chinese

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

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

  4. ASP.NET MVC+EF在服务端分页使用jqGrid以及jquery Datatables的注意事项

    引言: 本人想自己个博客网站出来,技术路线是用ASN.NET MVC5+EF6(Code First)+ZUI+各种Jquery插件,有了这个想法之后就开始选择UI,看了好多bootstrap的模板之 ...

  5. java访问webservce,保持会话,服务端保存session验证

    在进行程序开发的过程中,遇到一个问题,怎么保持会话. 因为一帮进行方法调用很少涉及到即时身份验证的. 例如: 1:客户端登录后服务端保存登录用户信息: 2:客户端持有验证通过key再次请求: 3:服务 ...

  6. 使用 PHP 来做 Vue.js 的 SSR 服务端渲染

    对于客户端应用来说,服务端渲染是一个热门话题.然而不幸的是,这并不是一件容易的事,尤其是对于不用 Node.js 环境开发的人来说. 我发布了两个库让 PHP 从服务端渲染成为可能.spatie/se ...

  7. Asp.net 中,在服务端向客户端写脚本的常用方法

    在Asp.net 服务端处理脚本,一般都用 ClientScriptManager ,即web窗体服务端的this.ClientScript.该对象比较常用的方法: 1.RegisterArrayDe ...

  8. asp.net网站作为websocket服务端的应用该如何写

    最近被websocket的一个问题困扰了很久,有一个需求是在web网站中搭建websocket服务.客户端通过网页与服务器建立连接,然后服务器根据ip给客户端网页发送信息. 其实,这个需求并不难,只是 ...

  9. asp.net mvc bootstrap datatable 服务端分页

    datatable 服务端分页 因项目需求变动,需处理大量数据,更改成服务端分页,自己两天的学习笔记 先上图[ jqueryui风格] 前端代码: @{ Layout = null;} <!DO ...

随机推荐

  1. Entity Framework Code First迁移基本面拾遗

    项目中用到了EF Code First和迁移,但发现有些方面似懂非懂.比如:如何在迁移文件中控制迁移过程?如果在迁移文件中执行SQL语句?如何使用Update-Database的其它参数?数据库在生产 ...

  2. 虚方法的调用是怎么实现的(单继承VS多继承)

    我们知道通过一个指向之类的父类指针可以调用子类的虚方法,因为子类的方法会覆盖父类同样的方法,通过这个指针可以找到对象实例的地址,通过实例的地址可以找到指向对应方法表的指针,而通过这个方法的名字就可以确 ...

  3. WPF与winform与silverlight的区别

    收到了一封学生的邮件: =========================== 金老师您好: 最近在学C#.NET,基本语法学习的差不多了,接下来准备学习图形界面设计部分.但是我目前对于.NET的Wi ...

  4. PHP ERROR : Call to undefined function curl_init()

    在使用PHP 的Curl方法时出现了以下错误 可能的解决办法: 在php.ini 中确保 启用了php_curl.dll组件 确保PHP版本 (PHP 4 >= 4.0.2, PHP 5, PH ...

  5. Oracle Essbase入门系列(二)

    本篇开始会一个三口之家的家庭财务数据库为例,讲述Essbase的功能和开发.为了说明EPM应用程序的管理和开发过程,会绕一些弯路,不使用EAS,而尽量用EPMA. 创建应用程序 首先登陆到Worksp ...

  6. scikit-learn主要模块和基本使用方法

    从网上看到一篇总结的很不错的sklearn使用文档,备份勿忘. 引言 对于一些开始搞机器学习算法有害怕下手的小朋友,该如何快速入门,这让人挺挣扎的.在从事数据科学的人中,最常用的工具就是R和Pytho ...

  7. JS验证 只能输入小数点,数字,负数。

    <script language="JavaScript" type="text/javascript"> function clearNoNum( ...

  8. XE6 FMX之控件绘制与显示

    中午,有个货随手买的2块钱的彩票,尼玛中了540块,这是啥子狗屎气运.稍微吐槽一下,现在开始正规的笔记录入.经常有朋友说为毛我的博客不更新了或者说更新的少了,为啥呢!一来自己懒了,没学习什么新的东西, ...

  9. Hadoop源代码中的build-main.xml

    在Hadoop的每一个Project中,都有build-main.xml,如下图所示: 这个文件其实是通过maven-ant插件生成的,在hadoop的每一个Maven工程中,都有一个pom文件,在p ...

  10. Android多国语言文件夹命名方式

    多國語言: 在res目錄下建立不同名稱的values文件來調用不同的語言包Values文件匯總如下:中文(中國):values-zh-rCN中文(台灣):values-zh-rTW中文(香港):val ...