Search code examples
next.jsnext-auth

Pass more data to session in Next-auth


We are doing OTP auth in our website. So in order to get authorized, a visitor enter his phone number in input and we send him a OPT number and he again enters the sent opt, then if it matches, we send him his account credendials (token, userID) if exists or we create new and we want to save that credentails in session useing next-auth.

This is where i got so far:

export default NextAuth({
  providers: [
    CredentialsProvider({
      credentials: {
        phoneNumber: { label: 'PhoneNumber', type: 'text' },
        code: { label: 'Code', type: 'text' },
        type: { label: 'Type', type: 'text' },
      },
      async authorize(credentials, req) {
        const user_needs = await requests.auth.signInEnterOtp(
          credentials.phoneNumber,
          credentials.code,
          credentials.type
        )
        return user_needs.ok ? true : null
      },
    }),
  ],
  callbacks: {
    async session({ session, user, token }) {
      return session
    },
  },
  secret: process.env.JWT_SECRET,
})

I need to save the user_needs in session but how can i pass it throuh authorize to session?

I tried returning the user_need in authorize but it was not passed to session callback.


Solution

  • Eventually i figured it out like this:

    async authorize(credentials, req) {
     const res = fetchUserInfo(credentials.opt)
     if(res.ok) return {user: res.data} // res.data contains whatever received from DB call => fetchUserInfo(credentials.opt)
    
     return null
    },
    callbacks: {
    
     async jwt({ token, user }) {
      // the user present here gets the same data as received from DB call  made above -> fetchUserInfo(credentials.opt)
    
      return { ...token, ...user }
     },
      async session({ session, user, token }) {
      // user param present in the session(function) does not recive all the data from DB call -> fetchUserInfo(credentials.opt)
    
      return token
     },
    },
    

    Edit: 2023 Feb 15

    I myself understood callback cycle better now:

    authorize --> jwt --> session
    

    jwt callback(cb) accepts the user object that authorize cb returns.

    By default jwt retuns the token and things return from there is then available in the token object of session cb

    Example:

    async authorize(credentials, req) {
      return { user: { role: 'ADMIN' } }
    },
    
    async jwt({ token, user }) {
      return { ...token, role: user.role }
    },
    
    async session({ session, token }) {
      return { ...session, token.role }
    }
    

    But when i use Providers, i won't have authorize cb, so to get user's role i need to query db in jwt cb but this callback runs a lot and i don't know what is the better option