Installation

npm install bcryptjs jsonwebtoken cookie

User Registration (API Route)

/app/api/auth/register/route.ts

This API endpoint registers a new user by hashing their password and storing it in a database.

import { hash } from "bcryptjs";
import { NextResponse } from "next/server";
import { db } from "@/lib/db"; // Assume a database connection

export async function POST(req: Request) {
  const { email, password } = await req.json();
  const hashedPassword = await hash(password, 10);

  // Store the user in the database
  await db.user.create({
    data: { email, password: hashedPassword },
  });

  return NextResponse.json({ message: "User registered successfully" });
}

Passwords are hashed using bcryptjs for security.

User Login (Generate JWT)

/app/api/auth/login/route.ts

This API endpoint verifies user credentials and returns a JWT token.

import { compare } from "bcryptjs";
import jwt from "jsonwebtoken";
import { NextResponse } from "next/server";
import { db } from "@/lib/db";

export async function POST(req: Request) {
  const { email, password } = await req.json();

  const user = await db.user.findUnique({ where: { email } });
  if (!user || !(await compare(password, user.password))) {
    return NextResponse.json({ error: "Invalid credentials" }, { status: 401 });
  }

  // Generate JWT token
  const token = jwt.sign(
    { id: user.id, email: user.email },
    process.env.JWT_SECRET!,
    { expiresIn: "1h" }
  );

  return NextResponse.json({ token });
}

If the email or password is incorrect, it returns a 401 Unauthorized error.

JWT is signed using a secret key (JWT_SECRET).

Protect API Routes (Middleware)

/app/api/protected/route.ts

This API endpoint requires authentication using JWT.

import jwt from "jsonwebtoken";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
  const token = req.headers.get("Authorization")?.split(" ")[1];

  if (!token) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET!);
    return NextResponse.json({ message: "Access granted", user: decoded });
  } catch {
    return NextResponse.json({ error: "Invalid token" }, { status: 403 });
  }
}

The token must be sent in the Authorization header (Bearer <token>).

If the token is missing or invalid, access is denied.

// Decode JWT (for debugging)
import jwt from "jsonwebtoken";

const token = "YOUR_JWT_HERE";
const decoded = jwt.decode(token);
console.log(decoded); // { id: "...", email: "...", exp: 1712345678 }