CORS errors can be tricky, especially when they block essential requests like `Authorization` headers.
Today, I tackled a cross-origin issue in a full-stack TypeScript project using Next.js (frontend) and NestJS (backend).
The Setup
- Frontend: Next.js running at `http://192.168.100.194:4000`
- Backend: NestJS API at `http://localhost:3000`
- Auth: JWT in `Authorization: Bearer ` header
I wanted to fetch user-specific subscription data by calling:
„`ts
fetch(’http://localhost:3000/api/subscriptions/view’, {
headers: {
Authorization: `Bearer \${token}`,
},
});
„`
The Problem
Everything worked locally — until I tried to fetch data from the frontend served at a different IP.
The browser blocked the request with:
„`
Access to fetch at 'http://localhost:3000/api/subscriptions/view’ from origin 'http://192.168.100.194:4000′
has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers.
„`
Root Cause
The NestJS backend was missing `Authorization` in its `allowedHeaders` config.
As a result, the browser preflight request (HTTP `OPTIONS`) failed.
The Fix
In `main.ts`, I updated the CORS setup:
„`ts
app.enableCors({
origin: [
process.env.FRONTEND_URL_LOCAL!,
process.env.FRONTEND_URL_PUBLIC!,
process.env.NEXT_PUBLIC_FRONTEND_URL_LOCAL!,
process.env.NEXT_PUBLIC_FRONTEND_URL_PUBLIC!,
],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE’,
allowedHeaders: [’Content-Type’, 'Accept’, 'Authorization’],
});
„`
The key was explicitly adding `’Authorization’` to `allowedHeaders`.
Validating the JWT
To ensure the token was parsed correctly on the frontend:
„`ts
const payloadBase64 = token.split(’.’)[1];
const decodedPayload = JSON.parse(atob(payloadBase64));
„`
And on the backend, NestJS used a custom `JwtStrategy` to attach user data, including `subscriberId`, for scoped access:
„`ts
async validate(payload: any) {
return {
id: payload.sub,
email: payload.email,
permissions: payload.permissions,
subscriberId: payload.subscriberId,
};
}
„`
Final Result
With CORS fixed and the token parsed correctly on both ends,
the dashboard successfully rendered user-specific subscription data:
„`ts
- Plan: {sub.plan_name}, Price: {sub.price} PLN
„`
Summary
- CORS isn’t just about domains — it’s about headers too.
- Always include `Authorization` in `allowedHeaders` when using Bearer tokens.
- Decode and inspect your JWTs to avoid silent failures.
- Validate configuration on both sides: browser and server.

Dodaj komentarz