代码之家  ›  专栏  ›  技术社区  ›  mnemosyn

使用MVC2的AJAX请求中的CSRF保护

  •  8
  • mnemosyn  · 技术社区  · 15 年前

    现在,我想防止该页面对抗CSRF。提交表格时,使用 Html.AntiForgeryToken()

    我目前的尝试是这样的 :

    我想重新利用现有的魔法。然而, HtmlHelper.GetAntiForgeryTokenAndSetCookie 是私密的,我不想在MVC里闲逛。另一个选项是编写一个扩展,如

    public static string PlainAntiForgeryToken(this HtmlHelper helper)
    {
        // extract the actual field value from the hidden input
        return helper.AntiForgeryToken().DoSomeHackyStringActions();
    }
    

    ValidateAntiForgeryTokenAttribute ,但它使用 AntiForgeryDataSerializer 这是私人的,我真的不想复制它。

    有什么建议如何以明智的方式做到这一点?我是不是遗漏了一些显而易见的东西?

    1 回复  |  直到 15 年前
        1
  •  10
  •   Darin Dimitrov    15 年前

    你可以用传统的 Html.AntiForgeryToken() 帮助程序在页面上的某个位置(不一定在表单中)生成一个隐藏字段,并将其包含在ajax请求中:

    var token = $('input[name=__RequestVerificationToken]').val();
    $.post(
        '/SomeAction', { '__RequestVerificationToken': token }, 
        function() {
            alert('Account Deleted.');
        }
    );
    

    [AcceptVerbs(HttpVerbs.Post)]
    [ValidateAntiForgeryToken]
    public ActionResult SomeAction() 
    {
        return View();
    }
    

    如果页面上有多个令牌,则可能需要指定要包含的令牌。由于现有辅助对象生成具有相同名称的隐藏字段,因此很难创建一个好的选择器,以便将它们放置在范围内:

    <span id="t1"><%= Html.AntiForgeryToken() %></span>
    <span id="t2"><%= Html.AntiForgeryToken() %></span>
    

    然后选择相应的令牌:

    var token = $('#t1 input[name=__RequestVerificationToken]').val();