Stuck on infinitely looping NextAuth authentication

40 Views Asked by At

I'm totally stuck on next auth infinitely looping on my next project. We recently made the main page of the app the defacto "home" page so I updated that page's name to index.tsx making it root. ever since then its like it gets trapped in this redirect hell. I have absolutely no idea what I'm doing wrong.

its worth noting our app doesn't have a sign on page perse but rather you're redirected to Okta's SSO flow. All recomendations I found for handling this use case said to create a signin.tsx which basically just tests session status then either calls the sign in function for Okta or redirects you to '/'. then in pages/index I've had a redirect also directing you to 'auth/signin' which docs have said to do in order to protect certain routes. but even without that bit of code in the getServerSideProps it STILL infinitely loops. I feel like its too much complexity? can someone who has a clue help me thin some of this out? what don't I need?

[...NEXTAUTH]

export const authOptionsFunction = (): AuthOptions => {
    return {
        providers: [
            Okta({
                //@ts-ignore
                clientId: process.env.OKTA_OAUTH2_CLIENT_ID as string,
                //@ts-ignore
                clientSecret: Config.OKTA_OAUTH2_CLIENT_SECRET as string,
                //@ts-ignore
                issuer: process.env.OKTA_OAUTH2_ISSUER as string,
                // clientId: process.env.OKTA_OAUTH2_CLIENT_ID as string,
                // clientSecret: process.env.OKTA_OAUTH2_CLIENT_SECRET as string,
                // issuer: process.env.OKTA_OAUTH2_ISSUER as string,
            })
        ],
        //@ts-ignore
        secret: process.env.NEXTAUTH_SECRET,
        //secret: process.env.NEXTAUTH_SECRET as string,
        session: { strategy: 'jwt'},
        callbacks: {
            async jwt({ token, account }: any) {
                if (account) {
                    token.accessToken = account.access_token;
                    token.idToken = account.id_token;
                    token.oktaId = account.providerAccountId
                }
                var tokenParsed = JSON.parse(Buffer.from(token.accessToken.split('.')[1], 'base64').toString());
                const dateNowInSeconds = new Date().getTime() / 1000
                if (dateNowInSeconds > tokenParsed.exp) {
                    throw Error("expired Okta access token");
                }
                return token;
            },
            async session({ session, token }: any) {
                // get our native current user data here 
                const res = await GET_CURRENT_USER(token);
                const { data } = await res.json();

                session.accessToken = token.accessToken;
                session.idToken = token.idToken;
                session.oktaId = token.oktaId;
                session.currentUser =  data;
    
                return session;
            },
            async signIn({ user, account, profile, email, credentials}) {
                return true;
            },
            async redirect({ url, baseUrl }) {
                // Allows relative callback URLs
                if (url.startsWith("/")) return `${baseUrl}${url}`
                // Allows callback URLs on the same origin
                else if (new URL(url).origin === baseUrl) return url
                return baseUrl
            }
        },
        debug: process.env.NODE_ENV === 'development',
        pages: {
            signIn: "/auth/signin",
        },

    }
}

export const authOptions: NextAuthOptions = authOptionsFunction()

export default NextAuth(authOptions);

MIDDLEWARE

export default withAuth(
    (req: NextRequest & { nextauth: { token: JWT | null } }) => {

        if (req.nextUrl.pathname.startsWith('/auth') || req.nextUrl.pathname.startsWith('/_next')) {
            return NextResponse.next();
        }
        // if there is no session
        if (!req.nextauth.token) {
            req.nextUrl.pathname = '/auth/signin';
            return NextResponse.redirect(req.nextUrl);
        }
        return NextResponse.next();
    },
    {
        callbacks: {
            authorized() {
                return true
            },
        },
        pages: {
            signIn: "/auth/signin",
        },

    }
);

SIGN IN COMPONENT

const SignIn = () => {

    const { status } = useSession();
    const router = useRouter();

    React.useEffect(() => {
        if (status === 'unauthenticated') {
            signIn('okta');
        } else if (status === 'authenticated') {
            router.push('/');
        }
    }, [status]);

    return (
        <>
        </>
    )
}

export default SignIn;

**PAGES / INDEX **

this little bit is just a part of getServerSideProps - the rest of the page is just a standard Page, ya know? fetch the props, pass the props, use the props.

     if (!session) {
         return {
             redirect: {
                 destination: '/auth/signin',
                 permanent: false,
             }
         }
     }
0

There are 0 best solutions below