Restricting Backend Routes in React + Node.js Using Secure Cookies and Middleware

Updated: Jul 14, 2025

AuthenticationSecurityCookiesExpressReact
Cover image for "Restricting Backend Routes in React + Node.js Using Secure Cookies and Middleware"

Securing Node.js Routes Using HTTP-only Cookies and Middleware

If you're building a React + Node.js app, storing tokens in HTTP-only cookies is a strong defense against XSS. But it’s not enough — you also need to properly restrict backend routes using middleware.

1. Set the Auth Token Securely

On successful login, send the token as a secure, HTTP-only cookie. This prevents JavaScript access on the client.


res.cookie('token', jwt.sign({ id: user.id }, JWT_SECRET, { expiresIn: '1d' }), {
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production',
  sameSite: 'Lax',
  maxAge: 24 * 60 * 60 * 1000
});
res.status(200).json({ message: 'Logged in' });
  

2. Middleware to Verify Cookie Token

Protect any route using a simple middleware function that checks for the token in the cookie.


// authMiddleware.js
const jwt = require('jsonwebtoken');

function authenticate(req, res, next) {
  const token = req.cookies.token;
  if (!token) return res.status(401).json({ error: 'Unauthorized' });

  try {
    req.user = jwt.verify(token, JWT_SECRET);
    next();
  } catch {
    res.status(401).json({ error: 'Invalid token' });
  }
}

module.exports = authenticate;
  

3. Apply Middleware to Protected Routes

Use your middleware on any route that requires authentication.


const express = require('express');
const authenticate = require('./authMiddleware');

const router = express.Router();

router.get('/profile', authenticate, (req, res) => {
  res.json({ userId: req.user.id });
});
  

4. Make Authenticated Requests from React

When calling protected routes from React, make sure to include credentials.


const res = await fetch('/api/profile', {
  method: 'GET',
  credentials: 'include'
});
const data = await res.json();
  

5. Common Pitfalls

  • Cookies not sent? Check that you're using credentials: 'include' and that the cookie domain matches.
  • Token never verified? Make sure the backend parses cookies using cookie-parser.
  • Token expired or missing? Check expiry and browser cookie settings (esp. with secure cookies on localhost).

Final Advice

Never trust the client. Always validate identity on the server using middleware. If you're not using HTTP-only cookies, assume any token stored in localStorage or sessionStorage can be stolen via XSS.