From 5d3dac0b2179df0266dee127e19ad5722fe32449 Mon Sep 17 00:00:00 2001 From: "santasri.pachhal" Date: Wed, 22 Jul 2026 16:18:17 +0530 Subject: [PATCH] refactor(api): add same-origin backend proxy for auth cookies --- .env.example | 7 +++++-- next.config.ts | 14 ++++++++++++++ src/services/api/auth.service.ts | 8 +------- src/services/axios/axios.ts | 10 +++------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/.env.example b/.env.example index 014ad78..89b80bc 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,5 @@ -# Backend API base URL (no trailing slash) -NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1 +# Server-only backend origin. Do not expose this as a NEXT_PUBLIC variable. +BACKEND_ORIGIN=http://localhost:8000 + +# Browser requests stay on the Next.js origin and are rewritten server-side. +NEXT_PUBLIC_API_URL=/backend/ diff --git a/next.config.ts b/next.config.ts index d680278..9f56915 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,21 @@ import type { NextConfig } from 'next'; +const backendOrigin = process.env.BACKEND_ORIGIN?.replace(/\/+$/, ''); + +if (!backendOrigin) { + throw new Error('BACKEND_ORIGIN is required'); +} + const nextConfig: NextConfig = { reactStrictMode: false, + async rewrites() { + return [ + { + source: '/backend/:path*', + destination: `${backendOrigin}/:path*`, + }, + ]; + }, }; export default nextConfig; diff --git a/src/services/api/auth.service.ts b/src/services/api/auth.service.ts index d62aaef..a21b796 100644 --- a/src/services/api/auth.service.ts +++ b/src/services/api/auth.service.ts @@ -14,9 +14,6 @@ export const authService = { const response = await axiosAuth.post( API_ROUTES.AUTH.LOGIN, payload, - { - withCredentials: true, - }, ); return response.data; }, @@ -24,14 +21,11 @@ export const authService = { const response = await axiosAuth.post( API_ROUTES.AUTH.REFRESH, {}, - { - withCredentials: true, - }, ); return response.data; }, logout: async (): Promise => { - await axiosAuth.post(API_ROUTES.AUTH.LOGOUT, {}, { withCredentials: true }); + await axiosAuth.post(API_ROUTES.AUTH.LOGOUT, {}); }, me: async (): Promise => { const response = await axiosClient.get(API_ROUTES.AUTH.ME); diff --git a/src/services/axios/axios.ts b/src/services/axios/axios.ts index bb065e7..0b6d3f3 100644 --- a/src/services/axios/axios.ts +++ b/src/services/axios/axios.ts @@ -7,6 +7,7 @@ const BASE_URL = ENV_CONSTANT.BASE_API_URL; const axiosClient = axios.create({ baseURL: BASE_URL, + withCredentials: true, headers: { 'Content-Type': 'application/json', }, @@ -14,6 +15,7 @@ const axiosClient = axios.create({ export const axiosAuth = axios.create({ baseURL: BASE_URL, + withCredentials: true, headers: { 'Content-Type': 'application/json', }, @@ -30,13 +32,7 @@ const isInvalidSessionResponse = (error: unknown) => { const refreshAccessToken = () => { if (!refreshPromise) { refreshPromise = axiosAuth - .post( - 'api/auth/refresh', - {}, - { - withCredentials: true, - }, - ) + .post('api/auth/refresh', {}) .then((response) => { const accessToken = response.data?.access_token;