skip to Main Content

I have been looking at implementing NextAuth with username and password credentials and I am not finding a way to return custom errors to the client side. It seems that I can only return a 200 ok or a redirection to an error page from the authorize method, where then you could add a custom error to a query string. However that is not a proper solution to my case as I need the client side to simply receive a custom error code or message from the sigIn call.

How do you return custom errors like

"Invalid email address"

"Account blocked"

"Invalid password"

Or any other customization required?

Thanks

2

Answers


  1. Chosen as BEST ANSWER

    I found the solution that I needed by implementing a signIn callback. The authorize method can return a custom object and the signIn callback catches it and handles it accordingly.

    See the documentation here

    // [...nextauth].js
    providers: [
    // credentials provider
    CredentialsProvider({
        type: 'credentials',
        credentials: {},
    
        // authorization function
        async authorize(credentials, req) {
            const { credential, password } = credentials
    
            if (myCustomCondition) {
              return { error: 'my custom error' };
            }
            return data // success
        }
     })
    ],
    callbacks: {
       async signIn({ user, account, profile, email, credentials }) {
          if(user?.error === 'my custom error') {
             throw new Error('custom error to the client')
          }
       }
    }
    

    On the client side we can evaluate the error message and act accordingly:

    const res = await signIn('credentials', {
        credential: data.credential,
        password: data.password,
        redirect: false
      })
      if (res?.status == 200) {
        push('/')
      } else if(res?.error === 'custom error to the client') {
        // handle this particular error
      } else {
        // handle generic error
      }
    

  2. If you are not using next-auth pages and using custom pages for your application, you have to set redirect to false in your login page when using signIn function, here is an example:

    // login.jsx
    
    const [datas, setDatas] = useState({ credential: '', password: '' })
    
    const handleSubmit = async e => {
        e.preventDefault()
        try {
          // siging in
          const res = await signIn('credentials', {
            credential: datas.credential, // can be changed to `email` or `username` or anything else
            password: datas.password,
            redirect: false // this is important
          })
          if (res?.status == 200) {
            push('/')
          } else {
            throw new Error(res?.error)
          }
        } catch (error) {
          console.log(error.message) // error in the provider
        }
    }
    

    and in the providers you have to throw the errors you want to be seen

    // [...nextauth].js
    
    providers: [
        // credentials provider
        CredentialsProvider({
            type: 'credentials',
            credentials: {},
    
            // authorization function
            async authorize(credentials, req) {
                const { credential, password } = credentials
    
                // admin profile
                let data = { credential : 'test', password: 'abcd' } // replace this
    
                if (!data) throw new Error('no user found')
                if (data.credential != credential) throw new Error('invalid credentials')
    
                // comparing the password
                const compared = data.password != password // replace this
    
                // checking if the password was correct
                if (!compared) throw new Error('invalid credentials')
    
                return data // success
            }
        })
    ],
    

    be careful of typos if I made any

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search