skip to Main Content

I am using Next.js version 13.4.4 and have an endpoint at http://localhost:5000/logout. In my src/app/logout/route.tsx file, I have the following code:

import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest) {
  return new NextResponse("POST: /logout");
}

Now, I am trying to call this endpoint from another application running at http://localhost:3000. However, I keep encountering the following error:

Access to XMLHttpRequest at 'http://localhost:5000/logout' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

How can I resolve this CORS error and successfully make a POST request to the http://localhost:5000/logout endpoint in Next.js 13.4.4?

 const response = await fetch('http://localhost:5000/logout', {
     method: 'POST',
     headers: {
          'Content-Type': 'application/json'
      },
      credentials: 'include',
  });

3

Answers


  1. I THINK this is what you’re asking for, not sure though. Gonna throw it in just in case though haha

    This is what I have set up, I think it might work well in your case if you are trying to restrict the fetch methods:

    In withMethods.ts (you can also have this in the same file)

    import type { NextApiHandler, NextApiRequest, NextApiResponse } from "next";
    
    export function withMethods(methods: string[], handler: NextApiHandler) {
      return async function (req: NextApiRequest, res: NextApiResponse) {
        if (!req.method || !methods.includes(req.method)) {
          return res.status(405).end();
        }
    
        return handler(req, res);
      };
    }
    

    In your API route file, in your case src/app/logout/route.tsx

    import { NextRequest, NextAPIResponse } from "next/server";
    import withMethods from "whereever you stored the file"
    
    export async function ApiHandler(req: NextRequest, res: NextApiResponse) {
      return res.status(200).send("whatever you want to send");
    }
    
    export default withMethods(["POST", "GET", ...], ApiHandler)
    

    Note: The withMethods code snippet is taken from Josh Tried Coding’s youtube channel and from this video (highly recommend watching it)

    Login or Signup to reply.
  2. cors should be handled in middleware. if you know express, we install cors package and register it in app.js. in nextjs13 you dont need to install this package

    in next.js middleware file

    const allowed=["enterallowedOriginsHere"]
    
    // Request type is globally available
    export function middleware(request:Request){
        // postman request do not have origin.
        // this code will allow requests from postman
        // If you do not want to allow postman requests, you can add logic to if condition
        const origin=request.headers.get("origin")
        if(origin && !allowed.includes(origin)){
             // return early
             return new NextResponse(null,{status:400,
                                           statusText:"BadRequest",
                                           headers:{'Content-Type':'text/plain'}})
       }
    }
    

    then from docs, you should alse set the headers in response inside route handlers. this is your route handler

    export async function POST(req: NextRequest) {
       const origin=request.headers.get("origin")
      return new NextResponse("POST: /logout",{
         headers: {
          'Access-Control-Allow-Origin': origin || '*',
          'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
          'Access-Control-Allow-Headers': 'Content-Type, Authorization',
        },
       });
    }
    

    you can also view this github discussion for different options

    Login or Signup to reply.
  3. Let’s understand the issue :

    CORS is a protocol defining the way your server is handling the special requests.

    What is special request

    If the server thinks that the same user requested the API (or resource ) from multiple domain then we can call that a special request.

    How server is getting such requests ?

    1. If we are visiting multiple websites then our browser is saving all kind of data from session to cookies and other ..
    2. If any of the website we are visiting, accidentally or purposefully requests the resource with our sessions and hit the server than what ?
    3. Because other website have a different origin so server can see all such origin as cross origin.
    4. It is obvious that such origins are requesting the server to share the resource from our details.
    5. So it can be seen as cross origin resource sharing.
    6. Server has mutiple methods to validate the orignal user request.

    Possible Solution to your problem :

    1. Set up a next.config.js file and add source and destination
    module.exports = {
        async rewrites() {
           return [
             {
                source: '/api/:path*',
                destination: 'http://localhost:4000/:path*'
             }
          ]
      }
    }
    
    1. Use the library CORS (https://www.npmjs.com/package/cors) and tell the server to accept from your address by adding the following lines
    app.use(cors({
        origin: 'http://127.0.0.1:3000',
    }))
    
    1. Add headers in next.config.js
    module.exports = {
      async headers() {
        return [
          {
            source: '/path/(.*)',
            "headers": [
            { "key": "Access-Control-Allow-Credentials", "value": "true" },
            { "key": "Access-Control-Allow-Origin", "value": "*" }, // Change this to specific domain for better security
            {
              "key": "Access-Control-Allow-Methods",
              "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT"
            },
            {
              "key": "Access-Control-Allow-Headers",
              "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
            }
          ],
          },
        ];
      },
    };
    
    1. To use PUT and POST without CORS, add following lines in /api/index.js
    export default async (req, res) => {
      const { method } = req;
    
      // This will allow OPTIONS request
      if (method === "OPTIONS") {
        return res.status(200).send("ok");
      }
    };
    

    Still having some confusions

    You can visit

    1. https://nextjs.org/docs/pages/api-reference/next-config-js/headers
    2. https://www.propelauth.com/post/avoiding-cors-issues-in-react-next-js
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search