skip to Main Content

I am working on a project that is based on NextJs v13 and uses Strapi v4 as the backend. I have a separate layout for the site, login, and dashboard. I worked on the login section and used NextAuth for authentication. But when I submit the login form, it does not recognize the authentication route and redirects to the http://localhost:3000/api/auth/error route.
The error
GET http://localhost:3000/api/auth/error 404 (Not Found)

This is my project folder structure.

enter image description here

This is the submission code.

 const onSubmit = async (e) => {
    e.preventDefault();
    const result = await signIn('credentials', {
      redirect: false,
      email: e.target.email.value,
      password: e.target.password.value,
    });
    if (result.ok) {
      router.replace('/');
      return;
    }
    alert('Credential is not valid');
  };

This is the […nextauth].j code:

import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import { signIn } from '../../../../services/auth';

export default NextAuth({
  providers: [
    CredentialsProvider({
      name: 'Sign in with Email',
      credentials: {
        email: { label: 'Email', type: 'text' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials, req) {
        
        if (credentials == null) return null;
       
        try {
          const { user, jwt } = await signIn({
            email: credentials.email,
            password: credentials.password,
          });
          return { ...user, jwt };
        } catch (error) {
          // Sign In Fail
          return null;
        }
      },
    }),
  ],
  callbacks: {
    session: async ({ session, token }) => {
      session.id = token.id;
      session.jwt = token.jwt;
      return Promise.resolve(session);
    },
    jwt: async ({ token, user }) => {
      const isSignIn = user ? true : false;
      if (isSignIn) {
        token.id = user.id;
        token.jwt = user.jwt;
      }
      return Promise.resolve(token);
    },
  },
});

And this the auth.js code:

import axios from 'axios';

const strapiUrl = process.env.NEXT_PUBLIC_STRAPI_API_URL;

export async function signIn({ email, password }) {
  const res = await axios.post(`${strapiUrl}/api/auth/local`, {
    identifier: email,
    password,
  });
  return res.data;
}

I searched alot to solve this problem but unfotunately I could not find any solution for this.

2

Answers


  1. I have not worked with NEXTJS but I think that the problem is here

    {
          name: 'Sign in with Email',
          credentials: {
            email: { label: 'Email', type: 'text' },
            password: { label: 'Password', type: 'password' },
     },
    

    to this

    {
          name: 'SignInWithEmail',
          credentials: {
            email: { label: 'Email', type: 'text' },
            password: { label: 'Password', type: 'password' },
    },
    

    the should not have any spaces.
    NOTE: I may be wrong,I have no experience whatsoever with NEXTJS

    Login or Signup to reply.
  2. In nextjs 13, we can not receive the api requests like nextjs 12, you need to create a file called route.js, inside the file you can receive different types of requests like POST, GET, PUT...

    In your case, create a file name it auth.js or any name you prefer, move your current nextauth.js file inside this and export it. example:

    import CredentialsProvider from "next-auth/providers/credentials";
    
    export const authOptions = {
      session: {
        strategy: "jwt",
      },
      providers: [
        CredentialsProvider({
          name: "Sign in",
          credentials: {
            email: {
              label: "Email",
              type: "email",
              placeholder: "[email protected]",
            },
            password: { label: "Password", type: "password" },
          },
          async authorize(credentials) {
           
            if (credentials == null) return null;
       
            try {
               const { user, jwt } = await signIn({
                   email: credentials.email,
                   password: credentials.password,
                  });
                   return { ...user, jwt };
    
               } catch (error) {
                 // Sign In Fail
                 return null;
               }
          },
        }),
      ],
    };
    

    then create a folder [...nextauth] under /api/auth and define your route.js file like this

    src/app/api/auth/[…nextauth]/route.ts

    import { authOptions } from "@/lib/auth";
    import NextAuth from "next-auth";
    
    // import the authOptions you have created inside the auth.js file
    const handler = NextAuth(authOptions);
    export { handler as GET, handler as POST };
    

    you can add more options to your authOptions, this one was a sample of what you need to do.
    Reference

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