7

ENVIROMENT


  • NextJS: 12.2.2
  • NextAuth: 4.10.3 (latest)
    • Provider: Credentials
  • Browser: Google Chrome
  • Node: LTS

ISSUE


Hello everyone

I'm using NextAuth for authentication with credentials provider and strategy jwt, but function getToken is always return null in my middleware, while my jwt callback in NextAuthOptions not return null

I checked token in cookie storage and trying decode token, result decode is still right

Variable enviroment NEXTAUTH_SECRET was added in file .env.local

CODE


src/page/api/auth/[...nextauth].ts

export const decode = async (data: any) => {
  const { secret, token } = data;
  const verify = jwt.verify(token, secret) as JWT;
  return verify;
};
export const encode = async (data: any) => {
  const { secret, token } = data;

  const payload = {
    username: token.username,
    email: token.email,
    _id: token._id,
  };
  const accessToken = jwt.sign(payload, secret, {
    expiresIn: '1209600s',
    algorithm: 'HS512',
  });
  return accessToken;
};

export const authOptions: NextAuthOptions = {
  providers: [
    CredentialsProvider({
      type: 'credentials',
      credentials: {},
      async authorize(credentials: any, req) {
        const { username, password } = credentials as {
          username: string;
          password: string;
        };

        try {
          const { data } = await client.mutate({
            mutation: login,
            variables: {
              userInput: {
                username,
                password,
              },
            },
          });

          const { user } = data.login;

          const response = {
            username: user.username,
            email: user.email,
            _id: user._id,
          };
          return response;
        } catch (error) {
          throw new Error('Unauthorized');
        }
      },
    }),
  ],
  session: {
    strategy: 'jwt',
    maxAge: 60 * 60 * 24 * 14,
  },
  jwt: {
    maxAge: 60 * 60 * 24 * 14,
    secret: process.env.SECRET,
    encode: encode,
    decode: decode,
  },
  pages: {
    signIn: '/auth/login',
    signOut: '/logout',
    error: '/auth/login',
    newUser: '/auth/register',
    verifyRequest: '/auth/verify',
  },
  callbacks: {
    async signIn({ user }) {
      return user ? true : false;
    },
    async session({ session, token }) {
      session.username = token.username;
      session.email = token.email;
      session._id = token._id;
      session.user!.name = token.username as string;
      session.user!.email = token.email as string;
      return session;
    },
    async jwt({ token, user }) {
      if (user?.username) {
        token.username = user.username;
        token.email = user.email;
        token._id = user._id;
      }

      return token;
    },
  },
};
export default NextAuth(authOptions);

src/middleware.ts

export default withAuth(function middleware(req: NextRequest) {}, {
  callbacks: {
    authorized: function ({ token }) {
      console.log(token); // token is always null

      return true;
    },
  },
});

export const config = { matcher: ['/chat', '/notifications'] };

2 Answers 2

4

Hey there had the same issue, updating to [email protected], as mentioned here, fixed it.

3
  • 2
    The whole discussion is useless in my case I am using Next 13.1.2 and this issue is still a nightmare Commented Apr 24, 2023 at 9:32
  • 1
    @BoyePanthera did you figure this out? I have the same issue Commented Jun 11, 2023 at 4:02
  • 1
    @TylerPashigian I couldn't find solution I had to create a Wrapper component on the frontend to the block pages from unauthorised access. Commented Jun 26, 2023 at 19:45
0

you should remove the secret option inside the jwt and put it outside. you should ensure you only have one secret value. it work for me on NextJs 13.4.12, the code should look like :

    secret: process.env.NEXTAUTH_SECRET,
    callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token = {
          ...token,
          id: user.id,
          //@ts-ignore
          role: user?.role,
          //@ts-ignore
          name: user?.fullName,
          //@ts-ignore
          picture: user?.avatar,
        };
        
        return token;
      }
      return token;
    },
    async session({ session, token }) {
    //@ts-ignore
      session.user.role = token.role;
      //@ts-ignore
      session.user.image = token.picture;
      //@ts-ignore
      session.user.name = token.name;


      return session;
    },
  },

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.