JianYA
JianYA

Reputation: 3024

ASP.NET Core Antiforgery Token without the form

Is it possible to have antiforgery tokens without forms? I have an ajax post call that I would like to make that needs an antiforgery token. However, most examples I have seen are asking for forms. This is what I have so far:

<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>

This just gets its input from a textbox and a button that is not attached to a form.

Upvotes: 0

Views: 3389

Answers (3)

Ryan
Ryan

Reputation: 20116

Ajax request could send the anti-forgery token in request header to the server.Refer to solution in 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);
        }
    });
   //...

});

Then you need to configure the antiforgery service to look for the XSRF-TOKEN header you have defined:

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

Of course,you need to use correct model binding and [ValidateAntiForgeryToken] attribute for your action.

Upvotes: 1

TempoClick
TempoClick

Reputation: 379

You need to add it manually. Try this:

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

And then post it with your data:

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

EDIT:

As @AndresAbel mentioned, you can copy the token from the form and send it in ajax post:

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

Then in in your script:

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

Then send it in ajax:

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

Don't forget to add the annotation [ValidateAntiForgeryToken] for your method in the controller.

Upvotes: 0

Anders Abel
Anders Abel

Reputation: 69260

The AntiforgeryToken is there to prevent cross site request forgery. So you should really use it. The easiest way to get one in jQuery is to render a dummy, hidden form on the page. Then the you can use your javaScript to copy the token from the dummy form and include it in your ajax post.

Upvotes: 0

Related Questions