Search code examples
next.jsnext.js13

How to Implement JWT Token Authentication for API Routes and Pages in Next.js 13?


I'm currently working on a Next.js application and I'm looking to implement JWT token authentication to protect my API routes and pages. I've researched various tutorials and documentation but I'm struggling to find a clear, concise solution tailored specifically for Next.js 13.

I have been through tutorials and blogs but I'm struggling to find a clear, concise solution tailored specifically for Next 13. Could someone provide a step-by-step guide or example code demonstrating how to implement JWT token authentication in Next 13. Any insights or suggestions would be greatly appreciated. Thank you!


Solution

  • I worked around and wrote this code and this might help others who is not wanting to use third party Auth.

    Verify Token

        import { jwtVerify } from "jose";
        export const getJwtSecretKey = () => {
        const secret = process.env.JWT_SECRET;
        if (!secret || secret.length === 0) {
            throw new Error("The environment variable JWT_SECRET is not set.");
        }
        return secret;
        };
        export async function verifyJwtToken(token:string) {
        try {
            const verified = await jwtVerify(
                token,
                new TextEncoder().encode(getJwtSecretKey())
            );
            return verified.payload;
        } catch (error) {
            throw new Error("Your token is expired");
        }
        }
    

    middleware.ts

    
        import { NextRequest, NextResponse } from "next/server";
       import {verifyJwtToken} from "@/lib/verifyToken"
       export async function middleware (request:NextRequest) {
    
        const path= request.nextUrl.pathname;
        const publicPath= ["/" ,"/auth"];
        const publicRoutes = ["/api/login","/api/register"]
    
        const isPublicPath = publicPath.includes(path);
        const isPublicRoute = publicRoutes.includes(path);
        const token = request.cookies.get("token")?.value;
    
        const verifiedToken = token && 
        ( await verifyJwtToken(token).catch((error)=>{
            console.log("Token verification error ",error)
        }) 
        )
    
        if(path.startsWith("/api")) {
            if(isPublicRoute){
                return NextResponse.next();
            }
            else if(!isPublicRoute && !verifiedToken){
                return NextResponse.json({message:"Unauthorized user"},{status:401})
            }
        }
    
        if (isPublicPath && verifiedToken) {
            return NextResponse.redirect(new URL("/dashboard",request.url))
        }
    
        if (!isPublicPath && !verifiedToken) {
            return NextResponse.redirect(new URL("/auth",request.url))
        }
        }
    
        export const config = {
        matcher :["/","/auth","/dashboard","/api/:path*"]
        }