Search code examples
next.jsnext-auth

next-auth.js with next.js middleware redirects to sign-in page after successful sign-in


I use next-auth.js with Google as my login provider and Django as my backend. To protect pages in next.js, I am trying to integrate next-auth.js with next.js middleware. Reference link

The issue I have is when the user is logged out, the middleware correctly routes to the login page. But after successful login, the user is redirected to the login page again. What am I missing?

middleware.js

export { default } from "next-auth/middleware"

export const config = { matcher: ["/jobs/:path*", "/accounts/:path*", "/profile/:path*", "/uploads/:path*"] }

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

import axios from "axios";
import NextAuth from "next-auth"
import Google from "next-auth/providers/google";
import { isJwtExpired } from "../../../constants/Utils";

 async function refreshAccessToken(token) {
  try {
    const response = await axios.post(
      process.env.NEXT_PUBLIC_BACKEND_BASE + "/api/auth/token/refresh/", {
      refresh: token.refreshToken
    });

    const { access, refresh } = response.data;
    return {
      ...token,
      accessToken: access,
      refreshToken: refresh,
    }
  } catch (error) {
    console.log(error)
    
    return {
      ...token,
      error: "RefreshTokenError"
    }
  }
}

export default NextAuth({
  providers: [
    Google({
        clientId: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        authorization: {
          params: {
            access_type: "offline",
            response_type: "code",
            scope:'openid profile email'
          }
        }
      }),
  ],
  callbacks: {
    async jwt({ token, user, account}) {
      // Initial sign in
      if (account && user) {

        if (account.provider === "google") {
          const { access_token: accessToken } = account;
          
          try {
            // make a GET request to the DRF backend
            const response = await axios.get(
              process.env.NEXT_PUBLIC_BACKEND_BASE + "/api/auth/register-by-token/google-oauth2/",
                {
                  params: 
                  {
                    access_token: accessToken
                  }
                }
            );
      
            const { access, refresh } = response.data;
            token = {
              ...token,
              accessToken: access,
              refreshToken: refresh,
            };
            return token
          } catch (error) {
            console.log(error)

            return {
              ...token,
              error: "NewUserTokenError"
            }
          }
        }

        return {
          ...token,
          error: "InvalidProviderError"
        }
      }

      if (isJwtExpired(token.accessToken)) {
        return refreshAccessToken(token)
      } else {
        return token
      }
    },
    async session({ session, token }) {
      session.accessToken = token.accessToken
      session.refreshToken = token.refreshToken
      session.error = token.error
      return session
    }
  }
})


Solution

  • Upgrading next-auth.js to 4.7.0 with next.js at 12.2.0 fixed it for me.