为什么我在授权过滤器中获得的AntiForgery令牌与我在浏览器中看到的令牌不同?

时间:2017-06-14 10:20:14

标签: ajax asp.net-mvc antiforgerytoken

在我的应用程序中,我使用 @ 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令牌检查时遗漏了什么?

非常感谢你。

2 个答案:

答案 0 :(得分:0)

我相信__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>');
        }

答案 1 :(得分:0)

事实证明,formToken与我在浏览器中看到的不同,因为请求没有通过ajax发送令牌并保持使用旧令牌。我没有在数据中发送令牌,而是将其移动到ajax beforeSend事件:

sendButtonClicked(){
    AsyncStorage.getItem("id").then(val => {
          fetch(`http://aaaa.000webhostapp.com/api/createPlate/${val}`, {
                method: 'POST',
                headers: {
                  'Accept': 'application/json',
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    p_number: this.state.letters + ' ' + this.state.numbers
                })
            }).then(response => {
                response.json().then(data => {
                    console.log(data)
                })
            })
        }).done()
    }

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