Building a web API is easy, but making it secure requires deliberate practices. Node.js backends are susceptible to CSRF, XSS, and unauthorized requests if not configured properly.
1. Secure CORS Configurations
Cross-Origin Resource Sharing (CORS) limits who can fetch resources from your API. Avoid setting `Access-Control-Allow-Origin: *` in production, especially for APIs requiring authentication.
import express from 'express';
import cors from 'cors';
const app = express();
const whitelist = ['https://myfrontend.com', 'https://admin.myfrontend.com'];
const corsOptions = {
origin: (origin, callback) => {
if (!origin || whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Blocked by CORS policy'));
}
},
credentials: true, // Allow cookies
};
app.use(cors(corsOptions));2. JWTs in HttpOnly Cookies
Do not store JWT tokens in localStorage. If your app is vulnerable to an XSS (Cross-Site Scripting) attack, scripts can read localStorage. Instead, use secure, HttpOnly, SameSite cookies.
res.cookie('token', token, {
httpOnly: true, // Prevents JS access
secure: process.env.NODE_ENV === 'production', // Https only
sameSite: 'strict', // Mitigates CSRF attacks
maxAge: 3600000, // 1 hour
});3. Security Headers with Helmet
Helmet sets various HTTP headers to secure Express apps by default, protecting against clickjacking, script injections, and mime sniffing.
import helmet from 'helmet';
// Apply helmet security headers
app.use(helmet());Following these security rules should be standard when initializing any production-ready Node.js API.



