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!
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*"]
}