Express.js and Vue.js – secure forms using CSRF token

Yes it’s something new on this blog – not only PHP, but also Node.js and Vue.js because I work on new project and use these technologies. Many, many things are completly new for me, but some of them are not. Good example is forms security: we must prevent attackers to make CSRF attacks and use tokens. Simple to say and now, in PHP world, very simple in usage – most of frameworks, most of template systems already have build-in solutions. With Express.js and Vue.js we can use available node modules, but we must still remember about some things. This post is about how use CSRF in that connection.

First of all, we must say, how our app works. Let’s say, Express.js (and Node.js) is or API server and Vue.js is on our webiste frontend – simple and clear. What next? We should do two things. First – create action on backend to handle user connection, to reply with sesssion token. Then we can use this token on frontend in for example, our other AJAX requests to API which use POST or PUT method – I think you will use another package to do this, some this example based on axios HTTP client. First step, install packakges and configure our backend.

Backend / API changes

We will use csurf package and it requires cookie-parser. Install them:

npm install cookie-parser csurf

Next step is to configure our app to use these packages. Edit your main server file (for example app.js):

var cookieParser = require('cookie-parser')
(...)
var app = express();
app.use(cookieParser())

Second step is to modify our routing rules and add CSRF middleware. It’s very simple:

// Add middleware
var csrf = require('csurf')
var csrfProtection = csrf({ cookie: true }) 
(...)
  
// Send CSRF token for session
router.get('/api/getcsrftoken', csrfProtection, function (req, res) {
    return res.json({ csrfToken: req.csrfToken() });
});

// Secure POST request by validate CSRF token
router.post('/api/formhandler', csrfProtection, function (req, res) {
  (...)
})

It’s all. Our backend is ready to handle requests and secure them. Now we can configure Vue.js part.

Vue.js and Axios changes

We must describe one thing: Vue.js is here only an example. You can use other frontend framework, you can use other libraries. It doesn’t matter, but I use Vue and Axios, so based on them in this post. We must only get our CSRF token and then use it on all other request. The simplest way is to overwrite default settings. See and example:

axios.get('/api/getcsrftoken').then((response) => {
  axios.defaults.headers.common['X-CSRF-TOKEN'] = response.data.csrfToken
}, (err) => {
  console.log(err)
})

And… yes, it’s all! All next Axios request will send X-CSRF-Token header with our token which can be verivied by our backend. Without that, POST/PUT/etc. requests securing by csrfProtection will be stopped.

What can I recommend? Use Vuex to store token and automatically get it when it’s necessary – add Vuex action to get token and also mutation to save response data into store. With that and saving store in user browser, we can use and refresh token easily.