Today, let's learn about setting up Protected Routes using NextAuth.
I had a hard time because the information about this was all over the place.
I'll try to write it based on the official documentation as much as possible.
1. Reason for Writing This

I've implemented login using NextAuth.
The problem was when I wanted to use route protection along with redirection.
I wanted to redirect both logged-in and non-logged-in users from the root path "/" to "/category".
And I wanted to block logged-in users from paths like "/profile" or "/login".
But there weren't many articles about this, and even chatgpt kept providing nonsense, which was frustrating.
2. NextAuth Official Documentation

I finally resolved it with search and official documentation.
The official documentation is indeed good.
If you access the link, you'll find how to combine NextAuth with middleware.
import { withAuth } from "next-auth/middleware";
export default withAuth(
// `withAuth` augments your `Request` with the user's token.
function middleware(req) {
console.log(req.nextauth.token);
},
{
callbacks: {
authorized: ({ token }) => token?.role === "admin",
},
}
);
export const config = { matcher: ["/admin"] };
The key here is that wrapping middleware with withAuth allows access to the requester's token.
If the token is not required, handle it inside the middleware, and if authorization is needed, pass it through callbacks.
It's possible to handle it in middleware itself, so it might not matter to pass it through callbacks.
3. Implementing the Functionality

Let's try applying this.
Wrap the middleware with withAuth.
Simply put, it's in the format withAuth(middleware, callbacks: {}).
When a request is made, it's processed once in the middleware and then passed on.
Let's dive into the code.
import { withAuth } from "next-auth/middleware";
import { NextResponse } from "next/server";
// Export middleware wrapped with withAuth
export default withAuth(
function middleware(req) {
// Redirect to /category upon accessing root URL(/
if (req.nextUrl.pathname === "/") {
return NextResponse.redirect(new URL("/category", req.url));
}
if (
req.nextauth.token?.authLevel !== "admin" &&
req.nextUrl.pathname.startsWith("/dashboard")
) {
return NextResponse.redirect(new URL("/category", req.url));
}
return NextResponse.next();
},
{
callbacks: {
authorized: ({ token, req }) => {
// Check permissions for dashboard
// Only check authentication for paths starting with profile
if (req.nextUrl.pathname.startsWith("/profile")) {
return !!token;
}
// Always return true for other paths
return true;
},
},
}
);
export const config = {
matcher: [
"/((?!api|_next/static|_next/image|.*\\.avif$).*)", // Exclude static files
"/",
"/dashboard",
"/profile/:path*", // Include only profile path in matcher
],
};
This way, all users are redirected to "/category" when accessing "/".
Users who are not "admin" are redirected when accessing the "/dashboard" path.
And logged-out users are shown a login screen if they try to access "/profile".
Other possibilities can be handled by manipulating tokens as needed.
4. Thoughts

I realized once again that keeping up with recent web development trends is not easy for the average person.
With express, there's so much accumulated data that just one AI input produces lines of code, but not with Nextjs.
There are many reviews on Reddit and Stack Overflow that AI can't keep up with the latest trends.
That's possibly why developers are still needed, at least for now.
I should improve my English skills to read the official documentation more diligently.
댓글을 불러오는 중...