Search code examples
reactjsmongodbauthenticationnext.jsnext-auth

How to return Mongo's _id with session in NextAuth?


I'm new to NextAuth. I'm using the NextAuth credentials provider with Mongodb. Based on NextAuth documentation, if I want to check the user session I could use useSession() in client components while getServerSession() for server components. By default, the session contains a user object which contains only name, email, and image properties. But what if I want to pass additional properties to my session like the _id that Mongodb generates when creating documents?

According to NextAuth, If I want to pass additional data to the session, I should add an acync callback session to my auth options. Since I'm using a JWT strategy which is the default strategy, I should add an async jwt callback before the session callback.

My auth options:

export const authOptions = {
    providers: [
        CredentialsProvider({
            name: 'Sign in',
            credentials: {},
            async authorize(credentials, req) {
                const { email, password } = credentials

                try {
                    await connectDB()
                    const customer = await Customer.findOne({ email })
                    if (!customer) null

                    //check whether the passwords are correct
                    const pwdComparisonResult = await bcrypt.compare(password, customer.password)
                    if (pwdComparisonResult) {
                        return customer
                    }

                    return null

                } catch (error) {
                    console.log('error ', error);
                }
            }
        }),
    ],
    callbacks: {
        async jwt(token, user, session) {
            //What I should write and return inside jwt?
        },

        async session({ session, token, user }) {
            //What I should write and return inside session?
        }
    },
    session: {
        strategy: "jwt"
    },
    pages: {
        signIn: '/login',
    }
}

As far as I know, the jwt will return a token and the session callback will receive this token and return a session. Is that true? Could someone explain how data flows between the authorize, jwt, and session and what logic I should be writing in the jwt and session callbacks in order to be able to access the mongo id along with the name and email properties?


Solution

  • The authorize callback receives the credentials and req parameters. The credentials parameter contains information obtained during the authentication process.

     // Callbacks are asynchronous functions you can use to control what happens when an action is performed.
      callbacks: {
        //   jwt callback is only called when token is created
        jwt: async ({ token, user }) => {
          // user is obj that we have received from authorize. in your case it is customer
          user && (token.user = user);
          // it should be Promise.resolve(token) otherwise you may get some error
          return Promise.resolve(token);
        },
        session: async ({ session, token }) => {
          // session callback is called whenever a session for that particular user is checked
          //   console.log("user in ...next auth api", token);
          // we can add more properties here to the session obj
          session.user = token.user;
          console.log("session", session);
          // since I get error, I return Promise.resolve(session)
          return Promise.resolve(session);
        },