通过AntiForgery Token提交多个AJAX表单

时间:2011-12-19 07:37:15

标签: jquery asp.net ajax asp.net-mvc forms

我使用AntiForgeryToken处理代码如下的多个表单提交

   public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var ctx = filterContext.HttpContext;
        var response = filterContext.HttpContext.Response;

        var request = filterContext.HttpContext.Request;
       string _antiForgToken =  request.Form.GetValues("__RequestVerificationToken")[0];
       if (ctx.Session["userform"] != null)
       {
           if (_antiForgToken.Equals(ctx.Session["userform"].ToString()))
           {
               //kill the request                   
               response.StatusCode = 400;
               response.StatusDescription = "Bad Request.";                   
           }
       }
       else
           ctx.Session["userform"] = _antiForgToken;

    }

代码在(正常)表单上工作正常,但是当表单通过ajax多次发布时(这是必需的功能)会出现问题我有一个表单例如Add Contacts用户添加联系人phone然后按回车键(ajax)请求正常完成但是再次以相同的形式用户选择电子邮件并按回车键我输入错误,因为AntiforgeryToken与我之前生成的AntiForgeryToken相同是如何刷新ajax成功的{{1}}

2 个答案:

答案 0 :(得分:1)

我不确定这是否是解决方案,但看起来很稳定:

Preventing CSRF With Ajax

答案 1 :(得分:0)

您可以通过在剃刀视图中调用以下函数来生成自定义AntiForgery令牌。

@functions{
  public string GetAntiForgeryToken()
  {
    string cookieToken, formToken;
    System.Web.Helpers.AntiForgery.GetTokens(null, out cookieToken, out formToken);
    return cookieToken + ":" + formToken;
  }
}
<script>
$.ajax({
  type: "POST",
  url: 'xxx',
  data: data,
  headers: { '__RequestVerificationToken': GetAntiForgeryToken()},
  success: function (data) {
    //if success
  },
  error: function (e) {
    //if error
  }
});
</script>

现在在属性过滤器中,您可以使用以下代码对其进行验证:

string tokenValue = request.Headers["__RequestVerificationToken"];
if (!String.IsNullOrEmpty(tokenValue))
{
    string[] tokens = tokenValue.Split(':');
    if (tokens.Length == 2)
    {
      cookieToken = tokens[0].Trim();
      formToken = tokens[1].Trim();
    }
}
System.Web.Helpers.AntiForgery.Validate(cookieToken, formToken);