9

I have a custom login page, which in turn calls the signIn() function when submitting the form.
I am only using the "Credentials" provider.

Server-side, I am just trying to throw an error so I can handle it on the frontend. Seems like something that would be easy.

I continue to get an error that states:
Error: HTTP GET is not supported for /api/auth/login?callbackUrl=http://localhost:4000/login

The url I get redirected to is:
http://localhost:4000/api/auth/login?callbackUrl=http://localhost:4000/login

Here is my code: pages/login.js (only relevant code. Rest is just layout.)

<form
    method="post"
    onSubmit={() =>
        signIn("credentials", {
            email: "test",
            password: "test",
        })
    }
>
    <label>
        Username
        <input type="email" />
    </label>
    <label>
        Password
        <input name="password" type="password" />
    </label>
    <button type="submit">Sign In</button>
</form>

pages/api/auth/[...nextauth.js]

import NextAuth from "next-auth";
import Providers from "next-auth/providers";

const options = {
    site: process.env.NEXTAUTH_URL,
    providers: [
        Providers.Credentials({
            id: "chatter",
            name: "Credentials",
            type: "credentials",
            credentials: {
                email: { label: "Email", type: "email", placeholder: "email@domain.com" },
                password: { label: "Password", type: "password" },
            },
            authorize: async credentials => {
                console.log("credentials:", credentials);
                throw new Error("error message"); // Redirect to error page
            },
        }),
    ],
    pages: {
        signIn: "login",
        newUser: null,
    },
};

export default (req, res) => NextAuth(req, res, options);
Gurnzbot
  • 3,742
  • 7
  • 36
  • 55
  • 1
    don't throw error in `authorize`. Either return null or true – A.Anvarbekov Feb 17 '22 at 10:34
  • It is actually fine to throw errors in `authorize` (might not be in the related legacy version?). It's probably required if you want to know what went wrong (was it the password? Is the email not yet confirmed?). It just doesn't seem to work with 'callbackUrl' (see @Ali Havasi's response). – HynekS Feb 24 '23 at 13:19
  • This might be to do with the fact that "login" takes the relative route, try using "/login" in the pages object – Salim May 19 '23 at 20:13

3 Answers3

5

You can use something like this:

signIn("credentials", {
     redirect: false, 
     email: "test",
     password: "test",
   })
   .then((error) => console.log(error))
   .catch((error) => console.log(error));
Mossen
  • 574
  • 5
  • 17
5

This answer helped me solve my issue:
https://stackoverflow.com/a/70760933/11113465

If you set redirect to false, the signIn method will return a promise of the following format:

{
    error: string | undefined // Error code based on the type of error
    status: number // HTTP status code
    ok: boolean // `true` if the signin was successful
    url: string | null // `null` if there was an error
}

And then you can handle the error as you like:

    const { error } = await signIn('credentials', {
          phone_number: phoneNumber,
          verification_code: code.toString(),
          redirect: false,
    });

    if (error) {
          // handle error
    } else {
          router.push(callbackUrl);
    }
Ali Havasi
  • 591
  • 6
  • 8
3

Do you check [...nextauth].js in pages/api/auth?

I had same issue, but I can fix [...nextauth].js move 'pages/api' to 'pages/api/auth'.