next.jscors

CORS issue with Next.js API routes and central middleware


I'm building a web application using Next.js, and I'm encountering issues related to CORS (Cross-Origin Resource Sharing) when trying to access my API routes. I've implemented a central middleware to handle CORS headers, but I'm still facing problems. Here's my setup:

I have a middleware.ts file where I'm handling CORS headers centrally for my Next.js API routes.

// middleware.ts

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const allowedOrigins = [
    'http://localhost:8888',
    'https://example.com',
    'https://another-example.com',
    // Add more URLs as needed
];

export function middleware(request: NextRequest) {
    if (request.method === 'OPTIONS') {
        // Handle preflight request
        const origin = request.headers.get('Origin');
        if (origin && allowedOrigins.includes(origin)) {
            const responseHeaders = new Headers()
            responseHeaders.append(
                'Access-Control-Allow-Methods',
                'GET, POST, OPTIONS'
            )
            responseHeaders.append(
                'Access-Control-Allow-Headers',
                'Content-Type, Authorization'
            )
            responseHeaders.append('Access-Control-Allow-Credentials', 'true')
            responseHeaders.append('Access-Control-Allow-Origin', origin)

            return new Response(null, {
                status: 200,
                headers: responseHeaders,
            })
        }
    }

    return NextResponse.next();
}

My me.ts API route uses this middleware to handle CORS headers.

// pages/api/me.ts

import { NextApiRequest, NextApiResponse } from 'next';
import { connectToDatabase } from 'lib/connectToDatabase';
import jwt from 'jsonwebtoken';

export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse
) {
    // Token handling and user data retrieval...
}

Despite setting up the middleware, I'm still receiving CORS-related errors when making requests from my frontend to the me.ts API route.

Error Message:

Access to fetch at 'http://localhost:3000/api/me' from origin 'http://localhost:8888' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I've verified the following points:

The middleware.ts middleware is imported correctly and applied to my API routes. The order of middlewares seems correct, and the CORS middleware should execute before my me.ts route handler. I've checked the client-side code to ensure that the requests are being made correctly and including the appropriate headers. Could there be something I'm missing or misunderstanding in the configuration of my CORS middleware and API route handler? How can I troubleshoot and resolve this CORS issue? Any insights or guidance would be greatly appreciated.


Solution

  • if (request.method === 'OPTIONS') {
        // Handle preflight request
    

    CORS headers need to be on the response to the "real" request and any preflight request (not just the preflight).


    CORS is a common requirement and has well-tested third party middleware which next.js uses in their example. I recommend switching to that instead of reinventing the wheel.