【问题标题】:why the AntiForgery token I got in authorization filter is different from the one I see in browser?为什么我在授权过滤器中获得的 AntiForgery 令牌与我在浏览器中看到的不同?
【发布时间】:2017-06-14 10:20:14
【问题描述】:

在我的应用程序中,我使用 @Html.AntiForgeryToken() 来装饰表单,然后我通过继承 IAuthorizationFilter 实现了一个 CustomAuthorizationFilter,该方法具有检查AntiForgery 用于包括 Ajax 调用在内的操作方法。

这是我的 CheckForAntiForgery 方法:

private static void CheckForAntiForgery(HttpRequestBase request)
{
    var cookie = request.Cookies["__RequestVerificationToken"];
    if (cookie != null)
    {
       var cookieToken = cookie.Value;
       var formToken = request.Headers["__RequestVerificationToken"];
       AntiForgery.Validate(cookieToken, formToken);
    }
}

我正在使用 Ajax 调用保存方法并将 form.serialize() 作为数据发送。我在浏览器中检查了 $('[name=__RequestVerificationToken]').val() 的值,并看到 "form.serialize()" 正在接收它价值。但是,当我进入上述方法时,'formToken' 与我在浏览器中看到的不同。 formToken 发送回应用程序后是否经过一些额外的处理?

另一个问题,在同一页面上,我尝试了多次保存点击,而我看到每次 $('[name=__RequestVerificationToken]').val() 的值发生变化,我在上面的方法中得到的 formToken 没有改变。有什么原因吗,还是我在执行 AntiForgery 令牌检查时遗漏了什么?

非常感谢。

【问题讨论】:

    标签: ajax asp.net-mvc antiforgerytoken


    【解决方案1】:

    我相信 __RequestVerificationToken 不会改变。

    下面的示例代码适用于我在使用 ajax 的 asp.net 身份登录中。 希望这会有所帮助。

    if (form.valid()) {
                $(this).addClass('ladda-button');
                var l = Ladda.create(this);
                l.start();
    
                var form1 = $('#__AjaxAntiForgeryForm');
                var token = $('input[name="__RequestVerificationToken"]', form1).val();
    
                $.ajax({
                    type: 'POST',
                    url: '/Account/Login',
                    data: {
                        __RequestVerificationToken: token,
                        Email: $('#username').val(),
                        Password: $('#password').val(),
                        RememberMe: false,
                    },
                    success: function (result) {
                        if (result.id === 1) {
                            mynotify('<div class="alert alert-success media fade in"><p><strong>success!</strong> ' + result.name + '</p></div>');
                            window.location.href = "\\";
                        } else if (result.id === 4) {
                            mynotify('<div class="alert alert-danger media fade in"><p><strong>Error!</strong> Login failed..</p></div>');
                        } else {
                            mynotify('<div class="alert alert-danger media fade in"><p><strong>Error!</strong> ' + result.name + '</p></div>');
                        }
                    },
                    error: function (result) {
                        mynotify('<div class="alert alert-danger media fade in"><p><strong>Error!</strong> Critical error occured, contact administrator</p></div>');
                        console.log(result);
                    }
                });
    
                l.stop();
    
            } else {
                $('body').addClass('boxed');
                mynotify('<div class="alert alert-danger media fade in"><p><strong>Error!</strong> Please try again.</p></div>');
            }
    

    【讨论】:

      【解决方案2】:

      原来 formToken 与我在浏览器中看到的不同,因为请求没有获得通过 ajax 发送的令牌并继续使用旧令牌。我没有在数据中发送令牌,而是将其移至 ajax beforeSend 事件:

      var token = $('input[name="__RequestVerificationToken"]', form).val();
      $.ajax({
            type: "POST",
            url: newurl,
            beforeSend: function (request)
            {
               request.setRequestHeader("__RequestVerificationToken", token);
            },
            data: form.serialize(),
            datatype: "JSON",
            success: function..,
            error: function..
      })
      

      现在每次发送新请求时它都会获取新令牌。

      【讨论】:

        猜你喜欢
        • 2020-11-10
        • 1970-01-01
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 2022-06-12
        • 2017-03-11
        • 1970-01-01
        相关资源
        最近更新 更多