I'm attempting to make a middleware for making API calls to a separate server but failing to make a redirect/rewrite. Paths which starts with /api/proxy
should be written without that prefix and route to the API server.
I'm using NextJS v.15.1.4, NextAuth 5.0.0-beta.25 and @rescale/nemo 1.4 for combining (future) middlewares.
My middleware.ts looks like this at the moment:
import { NextResponse } from "next/server";
import { cookies } from 'next/headers';
import { createMiddleware, type MiddlewareFunctionProps } from '@rescale/nemo'
import { auth } from 'auth';
const globalMiddlewares = {
before: async ({ request }: MiddlewareFunctionProps) => {
if (!request.url.includes("api/auth")) {
return;
}
auth()
},
};
const middlewares = {
"/api/proxy/*segments": [
async ({ request, response, context, event, forward, params }: MiddlewareFunctionProps) => {
const sessionCookieName = process.env.NODE_ENV === "development"
? "authjs.session-token"
: "__Secure-next-auth.session-token";
const cookieStore = await cookies();
const bearerToken = cookieStore.get(sessionCookieName);
request.headers.set("Authorization", "Bearer " + bearerToken?.value);
const newHeaders = new Headers(request.headers);
newHeaders.set("Authorization", "Bearer " + bearerToken?.value);
const newResponse = NextResponse.next({
request: {
headers: newHeaders
}
});
forward(newResponse);
},
async ({ request, response, context, event, forward, params }: MiddlewareFunctionProps) => {
const path = params()?.segments?.join("/");
return NextResponse.rewrite(new URL(path, process.env.NEXT_PUBLIC_API_BASE));
}
]
}
// create middleware
export const middleware = createMiddleware(middlewares, globalMiddlewares);
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
}
```
It seems like it's not possible to redirect or fetch data from an external server in combination with modified headers any longer according to: https://nextjs.org/docs/messages/middleware-upgrade-guide#edge-api-routes
The solution would be to intercept calls with a route handler. In this case :
// /app/api/proxy/[...all]/route.ts
import { NextResponse } from "next/server";
import { type NextRequest } from 'next/server'
// From https://nextjs.org/docs/messages/middleware-upgrade-guide#edge-api-routes
export const config = {
runtime: 'edge',
}
export async function GET(request: NextRequest) {
const sessionCookieName = process.env.NODE_ENV === "development"
? "authjs.session-token"
: "__Secure-next-auth.session-token";
const bearerToken = request.cookies.get(sessionCookieName);
if (!bearerToken) {
// TODO: return error.
return NextResponse.next();
}
const url = new URL(request.url);
const targetPath = url.pathname.replace("/api/proxy/", "");
const targetURL = new URL(targetPath, process.env.NEXT_PUBLIC_API_BASE)
const response = await fetch(targetURL.href, {
method: request.method,
headers: {
"Authorization": `Bearer ${bearerToken.value}`,
},
redirect: 'manual',
})
return response;
}
// TODO: Add other request handlers