1.首先在表单提交页面生成校验使用的Token
public ActionResult Index() { //Token验证需要使用的token string token = System.Guid.NewGuid().ToString(); this.HttpContext.Session["Token"] = token; ViewBag.token = token; return View(); }
2.视图页面在表单作用域下建立隐藏域
<input type="hidden" name="hiddenToken" id="hiddenToken" value="@ViewBag.token" />
3.建立验证Token逻辑的特性标签
public class PlatformActionFilter : FilterAttribute, IActionFilter { public PlatformActionFilter() { } public void OnActionExecuting(ActionExecutingContext filterContext) { string httpMethod = filterContext.RequestContext.HttpContext.Server.HtmlEncode(filterContext.RequestContext.HttpContext.Request.HttpMethod); if (httpMethod == "POST") { // page token // hiddenToken string cacheToken = filterContext.HttpContext.Request["hiddenToken"]; var session = System.Web.HttpContext.Current.Session["Token"]; //filterContext.HttpContext.Request.IsAjaxRequest() if (session != null) { if (cacheToken == session.ToString()) { System.Web.HttpContext.Current.Session["Token"] = "Success"; Logger.LogHelper.WriteErrorLog("提交成功!"); } else { System.Web.HttpContext.Current.Session["Token"] = "Erro"; Logger.LogHelper.WriteErrorLog("请不要重复提交!"); } } } } public void OnActionExecuted(ActionExecutedContext filterContext) { } }
4.提交控制器做验证判断token值是否为Success
[HttpPost] [PlatformActionFilter] public ActionResult Register(Users Usdata) { if (this.HttpContext.Session["Token"].ToString() == "Erro") { return WriteError("请不要重复提交!"); } //这里写正常的业务逻辑和返回 return WriteSuccess("注册成功!"); }
整个流程的验证思路就是在session中存放一个特殊标志。当表单页面被请求时,生成一个特殊的字符标志串,存在session中,同时放在表单的隐藏域里。接受处理表单数据时,通过过滤器的标签验证session是否合法,然后正常处理数据。除非走正常逻辑先进入到表单提交页面,然后才能正常处理Post请求。
还有就是检查HttpContext.Request.UserAgent
if (HttpContext.Request.UserAgent == "Fiddler")
{
WriteError("请求非法");
}