Custom server bodyParser and nextauth conflicting

119 Views Asked by At

I have my ...nextauth as guided in documentation like so:

enter image description here

I have a custom server as so:

app.prepare().then(() => {
    const server = express();

    server.use(cors())
    
    server.use('/authuser', authRoutes)
    server.use('/user', userBasicRoutes)
    server.use('/admin', userAdminRoutes)
    
    server.use(async(req, res, next) => {
      try {
        const parsedUrl = parse(req.url, true);
        await handle(req, res, parsedUrl)
      } 
      catch(err){
        console.error("Error occurred handling", req.url, err);
        res.statusCode=500;
        res.end("internal server error");
      }
    });
    ...........

It is working, my nextauth login is successful and I'm able to access my server routes and controller files (MVC) with the logged in user session using GET. However I realized I cannot pass request.body with POST requests to my router files without body parser. When I tried server.use(bodyParser.json()) nextauth stopped working. So I tried setting my routers individually with bodyParser like so:

server.use('/authuser', authRoutes)
server.use('/user', bodyParser.json(), userBasicRoutes)
server.use('/admin', userAdminRoutes)

But it's not working, body data is being passed but nextauth stop working with the following error message:

[next-auth][error][CLIENT_FETCH_ERROR] 
https://next-auth.js.org/errors#client_fetch_error undefined {
  error: {},
  url: 'http://localhost:3000/api/auth/session',
  message: undefined
}

Of course if I modify my /user router back to server.use('/user', userBasicRoutes), nextauth works again but I cannot pass request.body data in post request.

My GET is working with authentication and params, POST is also working with authentication session and request.params but the request.body not passing. Any suggestions to solve this issue?

Update Havent figured it out yet but made some headway in identifying the source of the error. Inside this route server.use('/user', bodyParser.json(), userBasicRoutes) I have this method:

const { getSession }=require("next-auth/react")

exports.getUserID=async(request, result, next)=>{
    const session=await getSession({req:request})
    if(session?.user?.id) return(session.user.id)
    else return(null)
}

The bodyParser seem to be conflicting with this method since when I alter my route to server.use('/user', userBasicRoutes) it's working again. I also tried putting this method in another route in which I didn't use bodyParser and it worked.

But once I use bodyParser and this method is called, I get the above error. I tried wrapping my method in try/catch block hoping to return null but the error is still displaying. Once this line execute const session=await getSession({req:request}) with bodyparser it's throwing the error

Anyone knows why bodyParser is throwing off my authentication method? I'm wondering if I send my bodyparsed request together with the original request to my controller so I could use the original in my authentication method and the parsed request for my request.body data?

1

There are 1 best solutions below

0
On

It could be happening because of how bodyParser.json() interacts with the getSession function, especially when the user is not logged in. You can try modifying your getUserID function to check for the presence of the req.body before attempting to access the session. If the request has a body (due to bodyParser.json()), then attempt to get the session. Otherwise, handle the case where the session cannot be obtained. Something like this might work,

const { getSession } = require("next-auth/react")

exports.getUserID = async (request, result, next) => {
  try {
    // Check if the request has a body before attempting to get the session
    const session = request.body ? await getSession({ req: request }) : null

    if (session?.user?.id) {
      return session.user.id
    } else {
      return null
    }
  } catch (error) {
    // ... Here handle any errors that might occur when getting the session
  }
}