0

I am new in Next.js and it turorials recommend using NextAuth.js for authentication and authorization.

My current app will use .Net 8 Web API as backend and have supported authentication and authorization to protect routes. It will return a JWT token and other necessary data back to client after users logged in. Every request from client need carry the JWT token in header.

I would like to use Next.js only as my frontend(the server components confused me a long time).

I'm happy with everything else about Next.js so far, but I am struggling dealing with authentication and authorization on NextAuth.

Now I can call my .Net login API in NextAuth actually, and it will return the right data from .Net including JWT, username, password and etc. And NextAuth can do authentication and authorization job.

However, it seems that NextAuth will generate another JWT itself rather than using the JWT returned back from .Net. Ideally, I only want the JWT from .Net.

I know I should be able to manually store the JWT token from .Net myself and manage it by, Redux or Context and etc like in vanilla React, but the point I am confusing is that I am using NextAuth.js, is there a way that can implement what I required?

Therefor what I really want to ask is what is the best practice when using .Net as backend and Next.js as frontend for authentication and authorization?

My code below:

auth.ts file:

async function getUser(email: string, password: string) {
    try {
        const res = await fetch(
            `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/Auth/Login`,
            {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    username: email,
                    password,
                })
            }
        )
        if (!res.ok) {
            throw new Error('Failed to fetch data123')
        }
        const user = res.json();
        return user || null;
    } catch (error) {
        console.error('Failed to fetch user:', error);
        throw new Error('Failed to fetch user.');
    }
}

export const { auth, signIn, signOut } = NextAuth({
    ...authConfig,
    providers: [
        Credentials({
            async authorize(credentials) {
                const parsedCredentials = z
                    .object({ email: z.string().email(), password: z.string().min(6) })
                    .safeParse(credentials);

                if (parsedCredentials.success) {
                    const { email, password } = parsedCredentials.data;
                    const user = await getUser(email, password);
                    console.log("auth.ts user:", user);
                    if (!user) return null;
                    return user;
                }

                return null;
            },
        }),
    ],
});

auth.config.ts file:

import type { NextAuthConfig } from 'next-auth';

export const authConfig = {
    pages: {
        signIn: '/login',
    },
    callbacks: {
        authorized({ auth, request: { nextUrl } }) {
            console.log("auth.config.ts auth:", auth);
            console.log("auth.config.ts auth?.user:", auth?.user);
            const isLoggedIn = !!auth?.user;
            const isOnDashboard = nextUrl.pathname.startsWith('/dashboard');
            if (isOnDashboard) {
                if (isLoggedIn) return true;
                return false; // Redirect unauthenticated users to login page
            } else if (isLoggedIn) {
                return Response.redirect(new URL('/dashboard', nextUrl));
            }
            return true;
        },
    },
    providers: [], // Add providers with an empty array for now
} satisfies NextAuthConfig;

middleware.ts file:

import NextAuth from 'next-auth';
import { authConfig } from './auth.config';

export default NextAuth(authConfig).auth;

export const config = {
    // https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher
    matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
};

Thank you very much for your help!

0