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();

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

// Add middleware
var csurf = 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'/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'] =
}, (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.

12 thoughts on “Express.js and Vue.js – secure forms using CSRF token

  1. Bro!, I tried this example, but only got invalid csrf token error.
    the axios.defaults.headers.common[‘X-CSRF-TOKEN’] is on the console properly when I use console.log function in
    sending request time.
    server side
    in csurf index.js file , I checked the value(req) function get the token properly.
    but always get invalid csrf token error
    I don’t know what I do wrong..

    1. I updated code and added line to create middleware:

      var csrfProtection = csrf({ cookie: true })

      Also, do you correctly save cookie / sends headers with token generated on first request (request without CSRF protection)?

    1. The same here, I updated code and added line to create middleware:

      var csrfProtection = csrf({ cookie: true })

      Also, do you correctly save cookie / sends headers with token generated on first request (request without CSRF protection)?

      1. How to send the correct cookie?

        axios version: v0.18.0*
        Environment: node v8.9.1, chrome 71.0.3578.98 (Official version) (64-bit), windows 8.1*
        I use VueJS (cli 3) & axios, and NodeJS – ExpressJS in the back-end. I am trying to secure my post user edit using CSRF token.

        Vue View (edit user – focus to mySubmitEd):

        this user
        {{name}} – {{surname}} – {{ perm }}


        import axios from ‘axios’
        import io from ‘’
        export default {
        name: ‘one-user’,
        data () {
        return {
        name: ”,
        surname: ”,
        perm: ”,
        csrf: ”,
        id: this.$,
        socket: io(‘localhost:7000’)
        mounted () {
        axios.get(‘http://localhost:7000/api/get-user/’ +
        .then(res => {
        const data = =
        this.surname = data.last_name
        this.perm = data.permalink
        this.csrf =
        axios.defaults.headers.common[‘X-CSRF-TOKEN’] = this.csrf
        .catch(error => console.log(error))
        methods: {
        mySubmit () {
        const formData = {
        }‘http://localhost:7000/api/delete-user’, formData)
        .then(this.$router.push({ name: ‘get-user’ }))
        .catch(error => console.log(error))
        mySubmitEd () {
        const formData = {
        last_name: this.surname,
        permalink: this.perm,
        _csrf: this.csrf
        console.log(formData._csrf)‘http://localhost:7000/api/update-user’, formData)
        .catch(error => console.log(error))

        server.js file:

        … const cookieParser = require(‘cookie-parser’); const csurf = require(‘csurf’); … app.use(cookieParser()); const csrfProtection = csurf({ cookie: true }); app.use(csrfProtection); …

        back-end controller which get the user:

        controller.getOneUser = function(req, res) { User.findOne({ _id: req.params.userId }).exec(function(err, user) { res.json({user, csrfToken: req.csrfToken()}); }); };

        My errors in NodeJS-exress console:
        ForbiddenError: invalid csrf token

        My errors in browser:
        POST http://localhost:7000/api/update-user 403 (Forbidden)

        I don’t know what is happened because I see in network tab(chrome) the csrf token is the same in the headers and what I send (example):

        X-CSRF-TOKEN: PddyOZrf-AdHppP3lMuWA2n7AuD8QWFG3ta0
        _csrf: “PddyOZrf-AdHppP3lMuWA2n7AuD8QWFG3ta0”

        I don’t know what I have miss here. I can’t find where is the problem.

        If you want more information please asked me to help you. What do you think (what do to for debugging)?

    1. Thank you for advice.
      There is a chaos in there I don’t know what to use.

      Could write a complete example please?
      Because the above didn’t work.

  2. I don’t think this solves the problem? This line is useful:

    axios.defaults.headers.common[‘X-CSRF-TOKEN’] = csrfToken

    but otherwise you are just providing an API endpoint to get the token. This adds another step to the would-be hackers workflow. They need to get the token then send their actual request.

  3. I didn’t realise that attackers can’t see the response of their queries. Basically the SOP prevents attackers from accessing the responses to their api calls. So we only need to protect from operations with side effects.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.