Ad

What Is The Optimal Way To Secure JWT In Cookies For A React/Redux Application?

Right now I'm working on a React/Redux full stack application and I'm working on setting up JWT auth and passing the JWT via cookies. I had a couple of questions on handling the CSRF token generated by the server.

1) Once you set the CSRF token on the server side, does it then get passed to the client? How exactly does it get passed? (I've seen examples where its passed in as an object, but the ones ive found weren't explained very well or just scarce)

server.js

// config csrf in server
app.use(csrf({
  cookie: {
    key: '_csrf',
    secure: true,
    httpOnly: true,
    sameSite: 'strict',
    maxAge: 86400
  }
}))

// Hits my api routes, and if these arent hit, the index.html file is rendered
app.use(routes)

// Route used to fetch the index html file
app.get('*', (req, res) => {
  let csrfToken = req.csrfToken()
  console.log(csrfToken) // This doesnt console log anything on the server side
  res.sendFile(path.join(__dirname, "./client/build/index.html"), {
    _csrf: csrfToken
  })
})

2) Once the CSRF token is set, should it be stored in the state of the application (Redux store) for persistent storage? Or would this be unnecessary?

3) On the client side, when I'm ready to submit data to a route via POST request, if I understand correctly, you'd have to include the input hidden field with the csrf variable like so:

<input type="hidden" name="_csrf" value=csrfToken/>

So when you submit a form, you'd include that input, then in the post request (assuming fetch or axios), you'd set the headers to include that csrf token, that way the server can compare it to the token the client is submitting to the route, am I understanding this correctly?

Thank you!

Ad

Answer

None of what you’ve asked specifically relates to react or redux. This is about request / response exchange with an HTTP server.

When using the the CSRF middleware, it automatically provides a CSRF tokens as a session cookie on request, and you’re expected to provide that back to the server on further requests.

1) CSRF tokens are usually set in a cookie by the server, or set as meta tag in the HTML. This code is generated uniquely per HTTP request to the server. It’s the applications responsibility to read the cookie/meta tag and then send it back to the server for future requests. One possible way is as a header: ‘X-csrf-token’ (https://en.m.wikipedia.org/wiki/Cross-site_request_forgery)

2) unnecessary in some cases: but that’s only by virtue of the fact that if the server sends a cookie header response, then your browser will always store that cookie, unless you have cookies turned off. When sending a request to the server, you need to retrieve that cookie and send it as the header above

3) I suggest you read the readme for express CSRF middleware (https://github.com/expressjs/csurf/blob/master/README.md), particularly this part about how the middleware looks for the CSRF tokens in responses or further requests:

The default value is a function that reads the token from the following locations, in order: • req.body._csrf - typically generated by the body-parser module. • req.query._csrf - a built-in from Express.js to read from the URL query string. • req.headers['csrf-token'] - the CSRF-Token HTTP request header. • req.headers['xsrf-token'] - the XSRF-Token HTTP request header. • req.headers['x-csrf-token'] - the X-CSRF-Token HTTP request header. • req.headers['x-xsrf-token'] - the X-XSRF-Token HTTP request header.

As you can see - how you provide it back to the server is up to you — most people choose a header, but it can be as a body or a get request query string.

Ad
source: stackoverflow.com
Ad