express csurf (csrf middleware) not working with XSRF in angularjs

Express and Angular both have their own csrf middleware. I cannot get them to work at all and there does not seem to be any coherent guide on the internet about this. My understanding is that express 4.0 uses csurf as its csrf middleware, and I have to set X-XSRF-TOKEN on angularjs.

There are scattered pieces about how to do this, with information that sometimes conflict:

How to test endpoints protected by csrf in node.js/express

angular, django and csrf

CSURF Angular Implementation

But I have tried them and they do not work. My _csrf is always undefined on the Angular clientside, and csurf always gives success despite no csrf token was given from the client.

Furthermore, I am using express-jwt to keep user session, so I am unsure if this will interfere with cookie-session (required by curf).

Here is my simple angular/express app for handling register with csrf (not working):

angular app.js

var app = angular.module('app', ['ngCookies', 'ui.router']);

app.config(function($stateProvider) {
    $stateProvider.state('register', {
        url: '/register',
        controller: 'RegisterCtrl',
        templateUrl: 'views/register.html'
    });
});

// register csrf
app.run(['$http', '$cookies', function($http, $cookies) {
    $http.defaults.headers.post['X-XSRF-TOKEN'] = $cookies.csrftoken;
}]);

// controller
app.controller('RegisterCtrl', ['$scope', '$cookies', '$http', 
    function($scope, $cookies, $http) {
        $scope.data = { email: "", password: "", _csrf: $cookies._csrf};

        $scope.submitForm = function() {
            // This will alert 'undefined'
            alert("This is csrf token: " + $scope.data._csrf);

            $http.post('/register', data).success(function(done) {
               console.log('success');
               var jwt_token = done["jwt_token"];
               // save token to local storage.
            }).error(function(err) {
               console.log('error');
            });
        }
    }
]);

express app.js

var express = require('express');
var app = express();
var http = require('http').Server(app);
var expressJwt = require("express-jwt");
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true});
app.use(bodyParser.json());

// csrf setup
var session = require('cookie-session');
var csrf = require('csurf');
app.use(session({
    secret: 'keyboard cat'
}));
app.use(csrf());
// This part taken from csurf guide:
// https://github.com/expressjs/csurf
app.use(function(err, req, res, next) {
    if (err.code !== 'EBADCSRFTOKEN') return next(err)
    res.status(403);
    res.send('session has expired or form tampered with');
});

app.post("/login", function(req, res) {
    var email = req.body.email;
    var password = req.body.password;

    // save user to db ...
    var jwt_token = // create and sign jwt token to be given back to registered user

    res.json({"jwt_token": jwt_token});
});

http.listen(3000, function() {
   console.log("Express started");
});

Now, if I submit the register form, the alert() will say the _csrf is undefined. On the expressjs side, app.post('/login') is run all the way through without having failed even though the csrf token should be bad (undefined since csrf on angular side is not working). This indicates that csurf is not working at all on the express side.

Can someone provide an in-depth explanation to integrating csurf in express 4.0, xsrf in Angular, and have them work together?

I had problems integrating both as well, and reached the following structure (just relevant parts):

express app.js

var cookieParser = require('cookie-parser');
var session = require('cookie-session');
var csrf = require('csurf');
app.use(session({
    secret: 'keyboard cat'
}));
app.use(cookieParser('secret'));
app.use(csrf());
app.use(function (req, res, next) {
    res.cookie("XSRF-TOKEN",req.csrfToken());
    return next();
});

In AngularJS side there is no need of changes. It identifies XSRF-TOKEN automatically.

Now, to explain the piece of code above, i need to refer to the csurf lib. It is a middleware to handle all the csrf authentication, but it implements another csrf library, called csrf. This csrf returns a "class" with four functions (secret, secretSync, create, verify).

What csurf does is, when you call its middleware, generates a secret through the secretSync method and stores in your session. You can access that through the variable req.session.csrfSecret. However, it does not execute the req.csrfToken method, which uses this secret to return a csrf Token. To return correctly the csrf token, you need to call it in another middleware.

Another important thing, the name of the returning cookie must be "XSRF-TOKEN", and not "_csrf". Therefore, Angular identifies it automatically and appends to HTTP requests the "X-XSRF-TOKEN", which is identified by the csurf middleware.

Hope it helps.