AntiforgeryToken post in Angular.js

Topics: Core, Customizing Orchard
Dec 6, 2013 at 10:23 PM
I'm trying to do a POST in an angular application in Orchard but I keep running into the "The required anti-forgery form field "__RequestVerificationToken" is not present." error.

I've tried generating the token in my razor view and passing that in the data body when I do the post, but Orchard never recognizes the token. I have verified that it is present in the request payload as well.

here is the token being generated in my view:
@using (Script.Foot()) {
    
    <script>
        appcreate.constant("AppSettings", {
            APIUrl: '@Url.Content("Create")',
            OrchardToken: '@Html.AntiForgeryTokenValueOrchard()'
        });
    </script>
}
here is the POST in my angular service:
    self.CreateApplication = function (app) {
        var defer = $q.defer();
        
        var dataObj = app;

        console.log(JSON.stringify(dataObj));
        
        //post the data here and add the antforgery token
        $http({
            url: AppSettings.APIUrl + "/CreatePOST?",
            method: "POST",
            data: {
                model: dataObj,
                __RequestVerificationToken : AppSettings.OrchardToken
            },
            dataType: "json",
            headers: {'Content-Type': 'application/json; charset=utf-8'}
        })
        
        .success(function (data) {
          defer.resolve(data);
        })
        .error(function (error) {
          defer.reject(error);
        });
        return defer.promise;
    };
The dataObj in the POST above is an object that looks like this:
    self.Application = {
        Id : 0,
        Name : "",
        Url: "",
        Active: true,
        IsTracked: true,
        Description: ""
    };
Here is the controller action I am trying to post to:
        [HttpPost, ActionName("Create")]
        public JsonResult CreatePOST(Application model)
        {
            var response = _appService.Create(model);
            return Json(response == null ? new Application() : model);
        }
I also know that there is a setting to enable or disable antiforgery for the entire module, but it seems to have no effect. Currently it is set to "AntiForgery: disabled" but I have also tried "AntiForgery: enabled" with no difference.

I've also tried putting the token in the request header and query string but neither worked. What am I doing wrong? I out of ideas on how I can pass the token in a way for Orchard to recognize it.
Dec 9, 2013 at 4:10 AM
Has anyone else ran into this? Maybe I'm not understanding how the Anti forgery token is used in Orchard. It just needs to be generated in the view via the @Html.AntiForgeryTokenValueOrchard() helper then passed to the controller in the body of the POST request correct?
Dec 9, 2013 at 5:53 AM
That is, lose the content type: json from the ajax post.

I would also recommend using url.action() instead of url.content() with action name Create, not CreatePost instead of adding CreatePost in the client script, since there is already an ActionName("Create") attribute for the action method.



Dec 9, 2013 at 3:49 PM
Thanks for the help. I took your advice and renamed the action and and used URL.Action() in the view. I tried both removing the content type header from my code and explicitly changing it to be form encoded but neither worked. It could be something with the way the HTTP module in Angular submits posts or something. I'm not sure.

Either way for now I was able to just disable the validation check in the module.txt file.

Thanks
Coordinator
Dec 10, 2013 at 2:34 AM
You should not disable the anti-forgery token. Use your browser's developer tools to visualize what's being sent to the server.