I’m encountering persistent CORS problems with my application, which functions correctly in a local environment. When deployed, requests from my Next.js frontend hosted on Vercel to my Express backend on Render face CORS restrictions. Despite applying all standard fixes, such as configuring Access-Control-Allow-Origin to allow all origins or redeploying, issues persist. My tech stack includes: Frontend: Next.js on Vercel, Backend: Node.js/Express on Render with JWT for authentication. In production, I’m receiving an error stating: ‘Access to XMLHttpRequest at ‘https://ai-pulse-backend.onrender.com/api/v1/auth/login’ from origin ‘https://ai-pulse-frontend.vercel.app’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.’ Additionally, I’ve observed: CORS request did not succeed. Status code: (null).
In my Express backend, I’ve implemented CORS middleware using the cors
package, allowing the frontend domain and enabling credentials. I’ve attempted to send required headers like Authorization and Content-Type from both sides. I verified the use of withCredentials: true
for cookies and confirmed that endpoints function properly using Postman. Despite my setup, issues still arise. Here’s the CORS implementation in my Express backend:
import express from 'express';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import routes from './routes/index';
const app = express();
const port = process.env.PORT || 8080;
const corsConfig = {
origin: ['http://localhost:3000', 'https://ai-pulse-frontend.vercel.app'], // Update this to your frontend URL
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
};
app.use(cors(corsConfig));
app.use(express.json());
app.use(cookieParser());
app.use((req, res, next) => {
const origin = req.headers.origin;
if (origin && corsConfig.origin.includes(origin)) {
res.header('Access-Control-Allow-Origin', origin);
}
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') {
res.status(200).end();
return;
}
next();
});
app.use(routes);
My Axios configuration on the frontend is set up to include credentials:
import axios from 'axios';
const API_URL = 'https://ai-pulse-backend.onrender.com/api/v1';
const axiosInstance = axios.create({
baseURL: API_URL,
withCredentials: true,
});
export default axiosInstance;
I also use Zustand for authentication:
login: async (email, password) => {
const response = await axiosInstance.post('/auth/login', { email, password });
const { accessToken } = response.data;
axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
}
Are there any extra headers or settings required for secure JWT authentication handling over CORS? Any advice or solutions would be immensely helpful! Thank you!