【问题标题】:ASP.NET Core Antiforgery Token without the form没有表单的 ASP.NET Core Antiforgery Token
【发布时间】:2019-01-29 11:54:19
【问题描述】:

是否可以有没有表格的防伪令牌?我有一个需要防伪令牌的 ajax 后调用。然而,我见过的大多数例子都是要求表格。这是我目前所拥有的:

<script>
    $(document).ready(function () {
        var SessionId = document.getElementById("Id").value;
        var form_data = {
            "SessionId": SessionId
        };
        $.ajax({
            url: "@Url.Action("GetHistory", @ViewContext.RouteData.Values["controller"].ToString())",
            method: "POST",
            data: JSON.stringify(form_data),
            contentType: "application/json",
            success: function (result) {
                console.log(result);
                var output = JSON.parse(result);
                for (var i = 0; i < output.length; i++) {
                    var p = document.createElement("span");
                    var q = document.createElement("li");
                    if (output[i].Mine == true) {
                        p.setAttribute("class", "Sender Me");
                        q.setAttribute("class", "Message");
                    } else {
                        p.setAttribute("class", "Sender");
                        q.setAttribute("class", "Message");
                    }
                    p.textContent = output[i].Name + " - " + moment(output[i].CreatedOn).format("DD-MM-YYYY HH:mm:ss");
                    q.textContent = output[i].Message;
                    document.getElementById("MessageList").appendChild(p);
                    document.getElementById("MessageList").appendChild(q);
                }

            },
            error: function (error) {
                console.log(error);
            }
        });

        $('#MessageList').stop().animate({
            scrollTop: $('#MessageList')[0].scrollHeight
        }, 2000);
        return false;
    });
</script>

这只是从一个文本框和一个未附加到表单的按钮中获取输入。

【问题讨论】:

  • 这怎么可能?呈现表单时会生成防伪令牌。
  • 那么,如果我在没有表单的情况下进行 ajax 调用,我的 POST 调用是否安全?
  • 我不是!但您可以使用带有防伪令牌的 ajax 提交表单。
  • 这在official docs 中有很好的介绍。你使用过那里详述的方法吗?

标签: javascript jquery asp.net asp.net-core


【解决方案1】:

Ajax 请求可以将请求头中的防伪令牌发送到服务器。参考Handle Ajax Requests in ASP.NET Core Razor Pages 中的解决方案。

<script type="text/javascript">
    function gettoken() {
        var token = '@Html.AntiForgeryToken()';
        token = $(token).val();
        return token;
        }   
</script>
<script>
$(document).ready(function () {
    var SessionId = document.getElementById("Id").value;
    var form_data = {
        "SessionId": SessionId
    };

    var headers = {};
    headers['XSRF-TOKEN'] = gettoken();//header name could be changed
    $.ajax({
        url: "/Home/testPost",
        method: "POST",
        data: JSON.stringify(form_data),          
        headers:headers,
        contentType: "application/json",


        success: function (result) {
            console.log(result);
            //...
        },
        error: function (error) {
            console.log(error);
        }
    });
   //...

});

然后你需要配置防伪服务来查找你定义的XSRF-TOKEN标头:

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc();
  services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}

当然,您需要为您的操作使用正确的模型绑定和[ValidateAntiForgeryToken] 属性。

【讨论】:

    【解决方案2】:

    AntiforgeryToken 用于防止跨站点请求伪造。所以你真的应该使用它。在 jQuery 中获得一个最简单的方法是在页面上呈现一个虚拟的隐藏表单。然后,您可以使用您的 JavaScript 从虚拟表单中复制令牌并将其包含在您的 ajax 帖子中。

    【讨论】:

      【解决方案3】:

      您需要手动添加。试试这个:

      var token = $("[name='__RequestVerificationToken']").val();

      然后将其与您的数据一起发布:

      data: { __RequestVerificationToken: token, JSON.stringify(form_data) }

      编辑:

      正如@AndresAbel 提到的,您可以从表单中复制令牌并将其发送到 ajax 帖子中:

      @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" })) { @Html.AntiForgeryToken() }

      然后在你的脚本中:

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

      然后用ajax发送:

      data: { __RequestVerificationToken: token, JSON.stringify(form_data) }

      不要忘记在控制器中为您的方法添加注释[ValidateAntiForgeryToken]

      【讨论】:

      • 嗨!你的方法几乎对我有用。我得到一个错误。来自数据的意外令牌:{} 部分。有什么问题吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 2017-05-20
      • 1970-01-01
      • 2014-10-16
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多