1

I have a next.js app that has several API routes that I am hoping to protect from users who are not logged in. Using next-auth, I understand that I can add the following code to each API route to achieve this.

import { getSession } from 'next-auth/client'

export default async (req, res) => {
  const session = await getSession({ req })

  if (session) {
    res.send({ content: 'This is protected content. You can access this content because you are signed in.' })
  } else {
    res.send({ error: 'You must be sign in to view the protected content on this page.' })
  }
}

However, I was wondering if it is possible to use API middlewares, so I am not repeating the same code over and over again? I read through the Next.js API middlewares documentation (https://nextjs.org/docs/api-routes/api-middlewares) and did the following:

import Cors from 'cors';
import { getSession } from 'next-auth/react';


function initMiddleware(middleware) {
  return (req, res) =>
    new Promise((resolve, reject) => {
      middleware(req, res, async (result) => {
        const session = await getSession({ req });
        if (!session) {
          return reject(result);
        }
        return resolve(result);
      });
    });
}

const cors = initMiddleware(
  Cors({
    methods: ['GET', 'POST', 'OPTIONS'],
  })
);

export default async function handler(req, res) {
  await cors(req, res);
  \* fetching from database *\

Although it works, the following error is returned when I tried to access the API route when unauthenticated, and it feels like I'm not doing it properly.

error - null
wait  - compiling /_error (client and server)...
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:561:11)
    at DevServer.renderError (/Users/alextung/Desktop/Projects/askit/node_modules/next/dist/server/next-server.js:1677:17)
    at DevServer.run (/Users/alextung/Desktop/Projects/askit/node_modules/next/dist/server/dev/next-dev-server.js:452:35)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async DevServer.handleRequest (/Users/alextung/Desktop/Projects/askit/node_modules/next/dist/server/next-server.js:325:20) {
  code: 'ERR_HTTP_HEADERS_SENT'
}
error - Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Would really appreciate some help on this given that this is my first time working with middlewares. Thank you!

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Alex
  • 11
  • 2
  • 1
    Make sure you are not sending a response before the function has completed. This will cause the error you are getting. "Error: Cannot set headers after they are sent." means that some function tried to set a header or status but you are already in the finished state. When you encounter this error, Look for callbacks that are accidentally called twice. – Bane Jan 11 '22 at 09:06
  • Can you show us the rest of the `handler` function in your API route? – juliomalves Jan 15 '22 at 17:52
  • 1
    @Bane Thanks for this! Yes this the problem - I ran a `res.status(200)` after I am already in the finished state. – Alex Jan 17 '22 at 05:47

0 Answers0