I'm trying to create a secure method of authentication for my Node.js REST API that will work both for direct API requests as well as from my React.js web application. I've done some reading on how to properly store authentication tokens to protect against XSS and CSRF, so I'd like to present what I've come up with to see if there are any holes in it, or if it will work at all.
This method will use a combination of JWT, localstorage (React app), and cookies (Node API).
The API has an endpoint
/authentication. When called, it will generate a CSRF token and include it in the payload of the JWT. It will then set a cookie (HttpOnly, secure) with the JWT, and return said JWT.
/authentication is called from my React.js web app, it will receive the JWT, and store just the CSRF token in localstorage.
Then, whenever the app needs to fetch a resource from the API, it will send the CSRF token in the header of each request.
The Node.js app will have a middleware that checks a few things:
- If the entire JWT is present, it will authenticate. This is the case where users are interacting with the API directly.
- If it's just the CSRF token, we will first verify the signature of the JWT in the cookie, and then compare the received CSRF with the one in the cookie. If they match, then it will authenticate.
My thinking is that this way, the JWT is never exposed on the web app for any attacks to occur.
Does this model seem secure enough?