How to set CSURF (Express Middleware) up to work with Postman?

Viewed 2443
2 Answers

Thanks for your question and answer, it helped solve part of the puzzle setting up Postman. I'm posting my own answer for a bit of clarity on a couple of points, with the bonus of automating copying the token into Postman requests

1. Cookie parser comes first

app.use(cookieParser())

2. Send _csrf cookie

app.use(csrf({ cookie: { httpOnly: true, }}))

This returns Cookie 1: _csrf. Using httpOnly is recommended because it keeps the cookie out of the reach of JavaScript and is more secure

3. Send XSRF-Token cookie

Sets a second cookie that needs to be returned with each request

app.use((req, res, next) => {
  res.cookie('XSRF-TOKEN', req.csrfToken())
  next()
})

4. Return XRSF-Token* header

This needs to be on every request (all that use POST, DELETE, etc) and is different after every call There are alternatives to using a header (a body property or query can be used instead) but using a header seems cleaner, especially when using JSON

a. Set up and send a GET request on Postman (Since get requests don't check for csrf by default)

b. Set up a POST request in Postman, set this header, using the cookie value from the GET request

XSRF-Token   abc123...

*Note the hyphen (-), not underscore (_)

4. Automatically set header in Postman

Postman automatically keeps and sends cookies, like a browser, but we need some way to obtain the token from the last request and copy it into our next request

Tests in Postman run a snippet of Javascript after each request and will work well for this purpose

I set this test up on one of my GET requests, so I'm sure it won't be invalid on the first request

// A Postman Test script
const xsrf_token = postman.getResponseCookie('XSRF-Token')
postman.setEnvironmentVariable('xsrf_token', xsrf_token.value)

Then, in your POST request's headers, switch out the copy pasted string for the environment variable

XSRF-Token   {{xsrf_token}}

Now you should be right to POST to your heart's content in Postman

I've had to relearn this a couple of times so I thought it'd be handy for everyone to see the breakdown:

In your server:

In index.js:

const app = require('./app')

app.set('port', 5000);

app.listen(app.get('port'), () => {
    console.log('App running on port', app.get('port'));
});

In app.js:

var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')

// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })

// create express app
var app = express()

// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())

app.get('/form', csrfProtection, function (req, res) {
  // pass the csrfToken to the view
  // res.render('send', { csrfToken: req.csrfToken() })
  res.send({csrfToken: req.csrfToken() })
})

app.post('/process', parseForm, csrfProtection, function (req, res) {
  res.send('data is being processed')
})

module.exports = app;

Start your server

In Postman:

GET Request:

Send a GET request to http://localhost:5000/form Postman GET request

Hit 'Send'. Below the request info you should see the following in the response data: enter image description here

Copy the string between the quotation marks. (In this example: H3DsAwqv-FuM06caBMOh6QZRFaILYgFyqFlA )

POST Request:

Set up a POST request to http://localhost:5000/process

enter image description here

Click the 'Body' tab and select the radio button for 'x-www-form-urlencoded'.

Enter a new key "_csurf" and paste the string value we received in the GET request.

Your POST request should now look like this set up: enter image description here

Hit 'Send'. You should now see this information: enter image description here

If you see 'data is being processed' then you know it's working!

I made a YouTube tutorial in case this makes things easier: https://youtu.be/QruvuwM-kkU

Related