Issue with NextAuth v4 Credentials Provider failing to provide an Id when requested

After successfully implementing next-auth for login, I encountered an issue where the user id from the database was not showing up in the session. Only the values that I provided as null were displaying.

import NextAuth from 'next-auth'
import CredentialProvider from 'next-auth/providers/credentials'
import connectMongo from '../../../lib/db'
import User from '../../../models/userModel'

export const authOptions = {
  session: {
    strategy: 'jwt',
  },
  providers: [
    CredentialProvider({
      async authorize(credentials) {
        await connectMongo()
        const u = await User.findOne({ username: credentials.username })
        console.log(u.id)
        if (u) {
          return {
            id: u.id,
            name: null,
            email: null,
            image: null,
          }
        }

        // login failed
        return null
      },
    }),
  ],
}

export default NextAuth(authOptions)

Although the login process was successful without any errors, only {email: null, image: null, name: null} were returned and the user id was missing from the props. When I tried to omit null values, it resulted in a SerializableError: Error serializing .session.user.name returned from getServerSideProps in "/authenticated". Reason: undefined cannot be serialized as JSON. Please use null or omit this value.

import { authOptions } from './api/auth/[...nextauth]'
import { unstable_getServerSession } from 'next-auth/next'

function Authenticated(props) {
  return <div>Authenticated</div>
}
export default Authenticated

export async function getServerSideProps(context) {
  const session = await unstable_getServerSession(
    context.req,
    context.res,
    authOptions
  )

  if (!session) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    }
  }

  return {
    props: {
      session,
    },
  }
}

Upon checking the session in getServerSideProps after a successful login, it returns an empty object with no errors.

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

function Authenticated(props) {
  console.log(props)
  return <div>Authenticated</div>
}
export default Authenticated

export async function getServerSideProps(context) {
  const session = await getSession({ req: context.req })

  if (!session) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    }
  }

  return {
    props: { session },
  }
}

Answer №1

To enhance the NextAuth configuration/settings object, one approach is to introduce a callbacks property.

An illustration of this concept involves integrating the callbacks property to locate and transmit additional details to the session.

export default NextAuth({
  session: {
    jwt: true,
  },
  callbacks: {
    session: async (session) => {
      if (!session) return;
      const client = await connectToDatabase();
      const usersCollection = client.db().collection('users');
      const userData = await usersCollection.findOne({
        email: session.user.email,
      });

      return {
        session: {
          user: {
            id: userData._id,
            email: userData.email
          },
          extra: {
            test: "It worked!"
          }
        }
      };
    },
  },
  providers: [
    Providers.Credentials({
      async authorize(credentials) {
        const client = await connectToDatabase();
        const usersCollection = client.db().collection('users');
        const user = await usersCollection.findOne({
          email: credentials.email,
        });

        if (!user) {
          client.close();
          throw new Error('No user found!');
        }

        const isValid = await verifyPassword(
          credentials.password,
          user.password
        );

        if (!isValid) {
          client.close();
          throw new Error('Could not log you in!');
        }

        client.close();
        return { email: user.email };

      },
    }),
  ],
});

In addition, for further insights on this topic, refer to the solution provided in relation to a similar question at this link: How do I add data to the client API in next-auth?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When updating the location.hash property via a click event, it appears to be set to

Check out the code snippet below: $(e).click(function() { console.log(this.href); location.hash = this.href; }); In this code snippet, e refers to a <li> element structured like this: <li href="#about">About</li> The location. ...

Analyzing the date provided as a string and comparing it to the current date using HTML and JavaScript

<html> <head> <script lang="Javascript"> function validateExpDate(){ var expdate ="24-10-2018"; var fields = expdate.split('-'); var date = parseInt(fields[0]); var month = parseInt(fields[1]); var year = parseIn ...

Ways to retrieve the text value of the first column using a button click event in JavaScript

As a beginner in HTML and JavaScript, I have a clear code provided below: HTML <tr> <td>1</td> <td>Info1</td> <td><input class="btn" value="Show" onclick="showTdSecond();" type="button"></td> & ...

A helpful tip for dynamically adjusting the canvas size is to utilize its height and width attributes to resize it whenever it undergoes a change

I am encountering an issue with the canvas element in my code. The canvas is supposed to update whenever its containing div is resized. window.addEventListener('resize',function() { let mapwidth = $('.canvas').attr("width") l ...

Leveraging arrays generated from two separate MySQL queries for dual selection functionality with JavaScript

I have successfully populated the first HTML select with results from the first query. Now, I would like to store the results from the second query in either a Json file or XML and then use plain javascript (not jQuery) to populate the second HTML select ...

I am having issues with the accuracy of my JavaScript number validation function

function CheckIfNumeric() { var quantity = jQuery("#txtShippedQuantity").val(); quantity = quantity.toString(); for (i = 0; i < quantity.length; i++) { var character = quantity.charAt(i); if (isNaN(character)) { ...

Posts created in Express using the node-postgres module are not being retrieved by queries in async routes

Running a basic query from an express route seems to be causing some issues for me: var router = require('express-promise-router')() const { Pool } = require('pg') const pool = new Pool({ user: 'user', password: 'pa ...

Unable to view cross domain cookies within the browser's development tools

I am currently working on a web application that has an Angular front end running on http://localhost:4200 and a NodeJs backend running on http://localhost:3000. When a user successfully logs in, a cookie is set from the backend containing a token. However ...

getting the child td element within a tr using a variable that changes dynamically

I'm facing an issue where I am trying to access the <td> of a <tr> using the jQuery .eq() function. The code snippet below illustrates what I am attempting: var foundElement = 3; var values = $(this).children("td:nth-child('" + foun ...

How to use the handleChange() function in React with various state properties

Explaining a bit about the handleChange function, which takes the name of the state element to be associated with it. Is there a specific reason why it has to be structured like this: handleInputChange(property) { return e => { this.setSta ...

Can one monitor a Vuex module in real time?

I have a single module imported into the Vuex store: import date from './modules/date-select'; export default new Vuex.Store({ modules: {date}, }); Is it possible to "watch" for changes in the entire module within a component? For example: ...

Can three photos be included in this code?

For this particular task, I am required to select 3 photos and create a button that allows me to cycle through them. The challenge lies in being able to select the photos from my file directory. Any assistance would be greatly appreciated! :D <!DOCTYPE ...

- Challenges with internal systems

I have a dialog window where I want to display a confirm dialog when clicking Cancel. To achieve this, I am creating a div element with some text that should be shown in the confirm dialog. However, the issue I'm facing is that the text intended for t ...

How can you integrate Dygraph into your React project alongside redux?

Lately, I've been facing some challenges while trying to integrate Dygraph into React (utilizing Redux). The Dygraph wrapper packages available on NPM don't seem to cooperate. Furthermore, the conventional method of using: <div id="graph"> ...

Implementing a time delay in the jQuery keyup() function following an Ajax request

I am currently facing a complex issue and I am uncertain about the best approach to tackle it. I have multiple textboxes lined up in a row that need to be filled in. Each time a value is entered into a textbox, I make an Ajax call to process that value. De ...

Is there a way to combine arrays with varying input values?

I am facing an issue where I have multiple text fields with the same name and class but with different values, each accompanied by a button. I am using Javascript to extract the value from each field by clicking on its respective button. I am able to store ...

Having trouble obtaining information from the state with Pinia Store

Currently, I am delving into the world of the composition API and Pinia with Vue3. I am facing an issue while calling an external API to fetch data and store it in the state of my store. The problem arises when I try to access this state from my page - it ...

In HTML, data can be easily accessed, however, JavaScript does not have the same

When trying to access the 'data' element in a JSON object, I have encountered an issue. The element is accessible when called from HTML, but not when called in JavaScript. HTML: <p>{{geoJson.data}}</p> JavaScript: let scope; let d ...

Tips for transferring data between pages in VUE js using paths

I currently have two pages - an add page and an edit page. I am looking to transfer data from the edit page to the add page. When the save button is clicked in the edit page, it should redirect the user back to the add page with a URL of /test/admin/testin ...

Issues rendering ThreeJS geometry data imported from Json file

Having been a dedicated user of this website for some time now, I must admit that this is the first instance where I find myself in need of posting a question. The issue at hand revolves around a Json file from which I extract data and manipulate it with m ...