reactjsauthenticationnext.jsmiddlewarenext-auth

Prevent authenticated users to access custom sign in page with next-auth middleware


we are currently developing an application with NextJS 13 using next-auth, so far everything is great. Our application uses a custom sign-in page with a CredentialsProvider and we protect our routes using the next-auth middleware. We would like to prevent our users from accessing /login if they are already authenticated. We managed to achieve this in the client with useSession() but we are looking for a way to have this logic in the middleware instead. Is this possible to achieve with the current next-auth middleware implementation? Below is our current middleware and route configurations. Thank you.

//middleware.ts
import withAuth from 'next-auth/middleware';

export default withAuth({
  pages: {
    signIn: `/login`,
  },
});

and

//route.ts
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';

const handler = NextAuth({
  pages: {
    signIn: `/login`,
  },
  session: {
    strategy: 'jwt',
  },
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        username: { label: 'Username', type: 'text' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials, req) {
        //auth logic here
      },
    }),
  ],
});

export { handler as GET, handler as POST };

Solution

  • This is working for us. Also credits to @Yilmaz, this is based on his answer.

    import { getToken } from 'next-auth/jwt';
    import { withAuth } from 'next-auth/middleware';
    import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';
    
    export default async function middleware(req: NextRequest, event: NextFetchEvent) {
      const token = await getToken({ req });
      const isAuthenticated = !!token;
    
      if (req.nextUrl.pathname.startsWith('/login') && isAuthenticated) {
        return NextResponse.redirect(new URL('/dashboard', req.url));
      }
    
      const authMiddleware = await withAuth({
        pages: {
          signIn: `/login`,
        },
      });
    
      // @ts-expect-error
      return authMiddleware(req, event);
    }