首页 > 代码库 > 防止XSRF 解决方案

防止XSRF 解决方案

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=http://www.mamicode.com/"@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() == "Success")
            {
                return WriteError("erro");
            }
            //这里写正常的业务逻辑和返回
              return WriteSuccess("注册成功!");
        }    

整个流程的验证思路就是在session中存放一个特殊标志。当表单页面被请求时,生成一个特殊的字符标志串,存在session中,同时放在表单的隐藏域里。接受处理表单数据时,通过过滤器的标签验证session是否合法,然后正常处理数据。除非走正常逻辑先进入到表单提交页面,然后才能正常处理Post请求。

防止XSRF 解决方案