Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JWT to store data in NextAuth

I return the following JSON after confirming credentials:

{username: 'foo', name: 'bar', type: 123}

However, NextAuth does not allow me to store all the fields due to model limitations, so what it returns in JWT to client is:

{name: 'bar', email: null, image: null}

My [...nextauth].js setup is very basic:

providers: [
    Providers.Credentials({
        async authorize(credentials) {
            const res = await fetch('http://localhost:3000/api/user', {
                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'credentials': JSON.stringify(credentials)
                }
            })
            const user = await res.json()
            
            if (user && !user.message) {
                return user
            } else {
                return null
            }
        }
    })
],

The only solution I came up with is to fake email field with JSON string in which I can store everything I need:

{name: 'bar', email: "{username: 'foo', type: 123}", image: null}

How can I do it properly? I tried looking into custom models (https://next-auth.js.org/tutorials/typeorm-custom-models), but it seems to be only about databases, which is not my case since I use JWT for session storage. Also what drawbacks I can encounter if I continue with my solution?

like image 554
Arctomachine Avatar asked Jan 25 '23 09:01

Arctomachine


1 Answers

You will need to persist the additional info through callbacks, at first through JWT's callback and then Session's callback:

  callbacks: {
    async jwt(token, user, account, profile, isNewUser) {
      // Since you are using Credentials' provider, the data you're persisting 
      // _should_ reside in the user here (as far as can I see, since I've just tested it out).
      // This gets called whenever a JSON Web Token is created (once) or updated
      if (user?.type) {
        token.status = user.type
      }
      if (user?.username) {
        token.username = user.username;
      }
      
      return token
    },
  
    async session(session, token) {
      session.type = token.type;
      session.username = token.username;
      
      return session
    }
  }
like image 97
Nelloverflow Avatar answered Feb 07 '23 19:02

Nelloverflow