簡體   English   中英

驗證防偽密鑰不適用於 ajax 帖子

[英]Validate Anti forgery key not working with ajax post

添加 我嘗試在 ajax post 請求中使用驗證防偽令牌,但響應是沒有找到根元素。 我刪除了防偽令牌,它運行良好。

這是我的代碼:

  function Save() {
        let GroupName = GetElementValue("GroupName");
        let GroupId = GetElementValue("GroupId");
        var Group = {
            __RequestVerificationToken: gettoken(),
            GroupId: :1",
            GroupName: "My Group Name"
        };

        if (IsFormValid("GroupForm")) {
            AjaxPost("/Groups/AddGroup", Group).done(function () {
                GetGroups();
            });
        }
    }


     function gettoken() {
        var token = '@Html.AntiForgeryToken()';
        token = $(token).val();
        return token;
   }

function AjaxPost(url, data) {
    return $.ajax({
        type: "post",
        contentType: "application/json;charset=utf-8",
        dataType: "json",
        responseType: "json",
        url: url,
        data: JSON.stringify(data)
    });
}

我也試過這個:

$.ajax({
    type: "POST",
    url: "/Groups/AddGroup",
    data: {
        __RequestVerificationToken: gettoken(),
        GroupId: 1,
        GroupName: "please work"
    },
    dataType: 'json',
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',

});

這是后端:

  [HttpPost]
        [ValidateAntiForgeryToken]
        public void AddGroup([FromBody] GroupView Group)
        {
            if (Group.GroupName.Trim().Length>0)
            {
                bool existed = _context.Groups.Any(x => x.GroupName.ToLower().TrimEnd().Equals(Group.GroupName.ToLower().TrimEnd()));
                if (!existed)
                {
                    Groups group = new Groups()
                    {
                        GroupName = Group.GroupName
                    };
                    _context.Groups.AddAsync(group);
                    _context.SaveChanges();
                    int? groupId = group.GroupId;
                }
            }
        }

這是完美傳遞的參數

這是我的班級 GroupView

public class GroupView
{
    public string GroupId { get; set; }
    public string GroupName { get; set; }
}

我想使用正常發送帶有我的數據的串行令牌的方法,我怎樣才能使它工作? 任何幫助!

在ASP.NET Core中,您可以通過表單或標頭傳遞防偽令牌。 因此,我可以為您提供2種解決方案。

解決方案1.標頭

為了讓框架讀取頭,你需要配置令牌AntiforgeryOptions並設置HeaderNamenull值。 將此代碼添加到Startup.cs

//or if you omit this configuration 
//HeaderName will be "RequestVerificationToken" by default
services.AddAntiforgery(options =>
{
    options.HeaderName = "X-CSRF-TOKEN"; //may be any other valid header name
});

並在AJAX傳遞防偽令牌

function Save() {
    //..
    //no need to set token value in group object
    var Group = {
        GroupId: "1",
        GroupName: "My Group Name"
    };
    //..
}

function AjaxPost(url, data) {
    return $.ajax({
        type: "post",
        contentType: "application/json;charset=utf-8",
        dataType: "json",
        responseType: "json",
        headers: {
            "X-CSRF-TOKEN": gettoken()
        },
        url: url,
        data: JSON.stringify(data)
});

解決方案2.表格

您已經嘗試過通過表單傳遞令牌,但是沒有用。 為什么? 原因是IAntiforgeryTokenStore的默認實現(用於從請求中讀取令牌)無法從json讀取反偽造令牌,而是將其讀取為表單數據。 如果要使其工作,則不要對請求數據進行stringify處理,也不要從$.ajax調用中刪除contentType屬性。 JQuery將分別為您設置適當的內容類型並序列化數據。

//all other original code is unchanged, group needs to contain a token
function AjaxPost(url, data) {
    return $.ajax({
        type: "post",
        dataType: "json",
        responseType: "json",
        url: url,
        data: data
});

另外,在這種情況下,您還需要從操作參數中刪除[FromBody]屬性,以使模型綁定程序正確綁定模型

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddGroup(GroupView group)

對於FromBody ,它將從application/json綁定模型,但是CSRF不會從正文讀取令牌。

最簡單的方法是,可以將標頭添加到RequestVerificationToken

Controller

[HttpPost("/Groups/AddGroup")]
[ValidateAntiForgeryToken]
public void AddGroup([FromBody] GroupView Group)
{
}

Client

<script type="text/javascript">
    $(document).ready(function(){
        var Group = {
            __RequestVerificationToken: gettoken(),
            GroupId: 1,
            GroupName: "My Group Name"
        };

        AjaxPost("/Groups/AddGroup", Group).done(function () {
            GetGroups();
        });

    });
    function gettoken() {
        var token = '@Html.AntiForgeryToken()';
        token = $(token).val();
        return token;
    }

    function AjaxPost(url, data) {
        return $.ajax({
            type: "post",
            contentType: "application/json;charset=utf-8",
            dataType: "json",
            responseType: "json",
            url: url,
            headers: {
                "RequestVerificationToken": gettoken()
            },
            data: JSON.stringify(data)
        });
    }
</script>

您將必須在VIEW內的表單中生成令牌,如下所示:

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

然后,您可以像這樣在Javascript中獲取令牌的值:

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

最后,您可以像這樣通過AJAX將令牌發送給您的控制器:

$.ajax({
type: "POST",
url: "/Groups/AddGroup",
data: {
    __RequestVerificationToken: token ,
    GroupId: 1,
    GroupName: "please work"
},
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',

});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM