在asp.net mvc中使用ActionFilter防止重复提交
2014-06-25 14:34
567 查看
防止重复提交的好处:可以预防恶意用户发重复的帖子和垃圾信息出现.
解决方案:
需要创建一个自定义的ActionFilter,重写OnActionExecuting方法
public class PreventSpamAttribute: ActionFilterAttribute
{
public override void OnActionExecuting (ActionExecutingContext filterContext)
{ base.OnActionExecuting (filterContext);
}
}
定义几个属性
一个属性来处理请求之间的延迟。
有一种机制来唯一识别用户的请求(和他们的目标)。
一种机制来存储这些信息,因此,它是访问请求发生时。
ModelState的信息显示错误的输出属性来处理。
让我们开始增加的延迟,这将仅仅是一个整数的值,将表明(以秒为单位)请求一个特定的控制器动作以及一些额外的属性,将存储的信息处理显示的错误和无效的请求重定向之间允许的最小延迟:
public class PreventSpamAttribute : ActionFilterAttribute
{
//处理请求之间的延迟
public int DelayRequest = 10;
//防止多次请求时的错误提示信息
public string ErrorMessage = "Excessive Request Attempts Detected.";
//出错时URL重定向
public string RedirectURL;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
}
确定发出请求的用户和他们的目标
下一步,我们将需要一种方法来存储当前有关用户的信息,并在他们的要求是源于这样我们就可以正确识别。做到这一点的方法之一是将得到一些识别有关用户的信息(如IP地址)“ HTTP_X_FORWARDED_FOR “头(如果不存在,” REMOTE_ADDR “标头值回落)和可能附加用户代理(使用“ USER_AGENT “头),以及进一步磨练我们的用户。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//存储 HttpContext
var request = filterContext.HttpContext.Request;
//获取IP请求者的IP地址
var originationInfo = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress;
//Append the User Agent
originationInfo += request.UserAgent;
//目标URL信息
var targetInfo = request.RawUrl + request.QueryString;
base.OnActionExecuting(filterContext);
}
生成一个Hash来标识唯一请求
现在,我们有独特的要求为我们的用户和他们的目标信息,我们可以用它来生成哈希将存储和使用,以确定是否垃圾邮件的请求后,可能是有效的。
为此,我们将使用。NET加密库(System.Security.Cryptography)你的字符串值来创建一个简单的MD5哈希值,所以你需要ActionFilter正在申报包括适当的using语句:
using System.Security.Cryptography;
我们可以利用LINQ来执行我们的字符串很短的小单行转换到一个散列字符串,使用这条线:
//Generate a hash for your strings (this appends each of the bytes of the value into a single hashed string
var hashValue = string.Join("", MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(originationInfo + targetInfo)).Select(s => s.ToString("x2")));
内存储的哈希缓存
我们可以使用散列字符串作为重点,将被保存在缓存中,以确定是否即将请求是重复的,并进行相应的处理。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Store our HttpContext
var request = filterContext.HttpContext.Request;
//Store our HttpContext.Cache
var cache = filterContext.HttpContext.Cache;
//Grab the IP Address from the originating Request
var originationInfo = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress;
//Append the User Agent
originationInfo += request.UserAgent;
//目标URL信息
var targetInfo = request.RawUrl + request.QueryString;
//创建希哈值
var hashValue = string.Join("", MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(originationInfo + targetInfo)).Select(s => s.ToString("x2")));
//如果希哈值在缓存中,(重复提交)
if (cache[hashValue] != null)
{
//添加错误信息
filterContext.Controller.ViewData.ModelState.AddModelError("ExcessiveRequests", ErrorMessage);
}
else
{
//使用希哈值的key添加一个空对象到缓存中(决定是否过期)
//if the Request is valid or not
cache.Add(hashValue, hashValue, null, DateTime.Now.AddSeconds(DelayRequest), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}
base.OnActionExecuting(filterContext);
}
应用
//Displays your form initially
public ActionResult YourPage()
{
return View(new TestModel());
}
[HttpPost]
[PreventSpam]
public ActionResult YourPage(TestModel yourModel)
{
//If your Model was valid - output that it was successful!
if (ModelState.IsValid)
{
return Content("Success!");
}
//Otherwise return the model to the View
else
{
return View(yourModel);
}
}
//This action can only be accessed every 60 seconds and any additional requests within that timespan will
//notify the user with a custom message.
[PreventSpam(DelayRequest=60,ErrorMessage="You can only create a new widget every 60 seconds.")]
public ActionResult YourActionName(YourModel model)
{
//Your Code Here
}
解决方案:
需要创建一个自定义的ActionFilter,重写OnActionExecuting方法
public class PreventSpamAttribute: ActionFilterAttribute
{
public override void OnActionExecuting (ActionExecutingContext filterContext)
{ base.OnActionExecuting (filterContext);
}
}
定义几个属性
一个属性来处理请求之间的延迟。
有一种机制来唯一识别用户的请求(和他们的目标)。
一种机制来存储这些信息,因此,它是访问请求发生时。
ModelState的信息显示错误的输出属性来处理。
让我们开始增加的延迟,这将仅仅是一个整数的值,将表明(以秒为单位)请求一个特定的控制器动作以及一些额外的属性,将存储的信息处理显示的错误和无效的请求重定向之间允许的最小延迟:
public class PreventSpamAttribute : ActionFilterAttribute
{
//处理请求之间的延迟
public int DelayRequest = 10;
//防止多次请求时的错误提示信息
public string ErrorMessage = "Excessive Request Attempts Detected.";
//出错时URL重定向
public string RedirectURL;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
}
确定发出请求的用户和他们的目标
下一步,我们将需要一种方法来存储当前有关用户的信息,并在他们的要求是源于这样我们就可以正确识别。做到这一点的方法之一是将得到一些识别有关用户的信息(如IP地址)“ HTTP_X_FORWARDED_FOR “头(如果不存在,” REMOTE_ADDR “标头值回落)和可能附加用户代理(使用“ USER_AGENT “头),以及进一步磨练我们的用户。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//存储 HttpContext
var request = filterContext.HttpContext.Request;
//获取IP请求者的IP地址
var originationInfo = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress;
//Append the User Agent
originationInfo += request.UserAgent;
//目标URL信息
var targetInfo = request.RawUrl + request.QueryString;
base.OnActionExecuting(filterContext);
}
生成一个Hash来标识唯一请求
现在,我们有独特的要求为我们的用户和他们的目标信息,我们可以用它来生成哈希将存储和使用,以确定是否垃圾邮件的请求后,可能是有效的。
为此,我们将使用。NET加密库(System.Security.Cryptography)你的字符串值来创建一个简单的MD5哈希值,所以你需要ActionFilter正在申报包括适当的using语句:
using System.Security.Cryptography;
我们可以利用LINQ来执行我们的字符串很短的小单行转换到一个散列字符串,使用这条线:
//Generate a hash for your strings (this appends each of the bytes of the value into a single hashed string
var hashValue = string.Join("", MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(originationInfo + targetInfo)).Select(s => s.ToString("x2")));
内存储的哈希缓存
我们可以使用散列字符串作为重点,将被保存在缓存中,以确定是否即将请求是重复的,并进行相应的处理。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Store our HttpContext
var request = filterContext.HttpContext.Request;
//Store our HttpContext.Cache
var cache = filterContext.HttpContext.Cache;
//Grab the IP Address from the originating Request
var originationInfo = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress;
//Append the User Agent
originationInfo += request.UserAgent;
//目标URL信息
var targetInfo = request.RawUrl + request.QueryString;
//创建希哈值
var hashValue = string.Join("", MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(originationInfo + targetInfo)).Select(s => s.ToString("x2")));
//如果希哈值在缓存中,(重复提交)
if (cache[hashValue] != null)
{
//添加错误信息
filterContext.Controller.ViewData.ModelState.AddModelError("ExcessiveRequests", ErrorMessage);
}
else
{
//使用希哈值的key添加一个空对象到缓存中(决定是否过期)
//if the Request is valid or not
cache.Add(hashValue, hashValue, null, DateTime.Now.AddSeconds(DelayRequest), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}
base.OnActionExecuting(filterContext);
}
应用
//Displays your form initially
public ActionResult YourPage()
{
return View(new TestModel());
}
[HttpPost]
[PreventSpam]
public ActionResult YourPage(TestModel yourModel)
{
//If your Model was valid - output that it was successful!
if (ModelState.IsValid)
{
return Content("Success!");
}
//Otherwise return the model to the View
else
{
return View(yourModel);
}
}
//This action can only be accessed every 60 seconds and any additional requests within that timespan will
//notify the user with a custom message.
[PreventSpam(DelayRequest=60,ErrorMessage="You can only create a new widget every 60 seconds.")]
public ActionResult YourActionName(YourModel model)
{
//Your Code Here
}
相关文章推荐
- Asp.net MVC中防止HttpPost重复提交
- ASP.NET Web Form和MVC中防止F5刷新引起的重复提交问题
- Asp.net MVC中防止HttpPost重复提交
- Asp.net MVC中防止HttpPost重复提交
- Asp.net MVC中防止HttpPost重复提交
- 使用Post/Redirect/Get实现Asp.net防止表单重复提交
- Asp.net MVC中防止HttpPost重复提交
- 在ASP.NET Web Form和MVC中防止F5刷新引起的重复提交
- asp.net mvc 防止重复提交
- Asp.net MVC中防止HttpPost重复提交
- AspNetMvc 防止重复提交
- 移动项目开发笔记(asp.net防止页面刷新引起重复提交数据)
- Asp.Net 防止重复提交方案
- ASP.Net中防止页面刷新重复提交的几种方法
- ASP.Net中防止页面刷新重复提交的几种方法
- Asp.net页面防止重复提交
- Asp.Net防止刷新重复提交数据小记
- asp.net 点击按钮后置灰,防止重复提交的代码!
- ASP.Net中防止页面刷新重复提交的几种方法
- asp.net页面防止按钮重复提交的小技巧