Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I wish to query the API to get a CSRF token. Then set this token in the header of all HTTP requests.

Before I set the CSRF token as a constant for the angularJS app, I am experiencing some difficulties.

app.run(['$http', function($http) {

    var csrf = $http( { method: 'GET', url: 'api/csrf' })
            .success(function(data) {
                console.log("CSRF Success: " + data.token);
                return data.token;
            })
            .error(function(data) {
                console.log("CSRF ERROR: " + data);
            });

        console.log("CSRF TOKEN: " + csrf);
        $http.defaults.headers.common['X-Csrf-Token'] = csrf;
}]);

When I run my application, I get the following in my browser console:

CSRF TOKEN: [object Object] scripts.js?v=1400582971:32411
GET http://testapp/api/v1/supplier 400 (Bad Request) scripts.js?v=1400582971:17571
CSRF Success: zD7TrQWQWma0eHYtzM8NcgbvitB9XJzTCegjAVMg scripts.js?v=1400582971:32404

There are several things wrong here...

  • Firstly, CSRF Success should be outputted before CSRF TOKEN.
  • Secondly, CSRF TOKEN: [object Object] should be CSRF TOKEN: zD7TrQWQWma0eHYtzM8NcgbvitB9XJzTCegjAVMg
  • Thirdly, the reason for the 400 (Bad Request) is because the headers sent in the get request are X-Csrf-Token:[object Object]. The header should be X-Csrf-Token:zD7TrQWQWma0eHYtzM8NcgbvitB9XJzTCegjAVMg

I don't want the variable csrf to be an object. It needs to be an actual string value.

Once I have this working, I am looking to extract the http request out and do something like the following:

app.factory("CSRF_TOKEN", function($http) {

    var token;

    $http( { method: 'GET', url: 'api/csrf' })
                .success(function(data) {
                    console.log("CSRF Success: " + data.token);
                    token = data.token;
                })
                .error(function(data) {
                    console.log("CSRF ERROR: " + data);
                });
});

app.run(['$http', 'CSRF_TOKEN', function($http, CSRF_TOKEN) {
    $http.defaults.headers.common['X-Csrf-Token'] = CSRF_TOKEN.token;
}]);

MY SOLUTION TO PROBLEM:

var xhReq = new XMLHttpRequest();
xhReq.open("GET", "//" + window.location.hostname + "/api/csrf", false);
xhReq.send(null);

app.constant("CSRF_TOKEN", xhReq.responseText);

app.run(['$http', 'CSRF_TOKEN', function($http, CSRF_TOKEN) {

    console.log("Injected CSRF: " + CSRF_TOKEN);

    $http.defaults.headers.common['X-Csrf-Token'] = CSRF_TOKEN;
}]);
share|improve this question
    
Problem Solved... See updated solution. I am all ears for better alternative solutions. –  Gravy May 20 at 12:31

1 Answer 1

Your original solution didn't work because you are expecting the $http.get to return your token but in fact this method returns a promise. The actual data, your token, is returned asynchronously via the the success function.

Your original code should probably look something like this:

$http({ method: 'GET', url: 'api/csrf' })
        .success(function(response) {
            var token = response.data.token;
            console.log("CSRF Success: " + token);
            $http.defaults.headers.common['X-Csrf-Token'] = token;
            //carry on with processing
        })
        .error(function(response) {
            console.log("CSRF ERROR: " + response.status);
});
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.