Day#18 Solving the „CORS error with Authorization header” in Next.js and NestJS

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).

mariusz
mariusz
20 posts
2 followers

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.

Fediverse Reactions

Opublikowano

w

,

przez

Tagi:

Komentarze

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *