Next.js Discord

Discord Forum

IP based rate limit with next-auth

Unanswered
Parson Russell Terrier posted this in #help-forum
Open in Discord
Parson Russell TerrierOP
Hi i'm trying to implment rate limit with next-auth and i'm getting this error
Login Failed: TypeError: Failed to construct 'URL': Invalid URL
    at _callee6$ (index.js:336:21)
    at tryCatch (regeneratorRuntime.js:45:16)
    at Generator.<anonymous> (regeneratorRuntime.js:133:17)
    at Generator.next (regeneratorRuntime.js:74:21)
    at asyncGeneratorStep (asyncToGenerator.js:3:17)
    at _next (asyncToGenerator.js:17:9)

here's my middleware code
import { NextRequest, NextResponse } from "next/server";
export { default } from "next-auth/middleware";

interface RateLimitData {
  count: number;
  lastReset: number;
}

const rateLimitMap = new Map<string, RateLimitData>();

function rateLimit(req: NextRequest) {
  const forwardedFor = req.headers.get("x-forwarded-for");
  const ip = forwardedFor ? forwardedFor.split(",")[0] : "unknown";
  const limit = 4;
  const windowMs = 60 * 1000;
  if (!rateLimitMap.has(ip)) {
    rateLimitMap.set(ip, {
      count: 0,
      lastReset: Date.now(),
    });
  }
  const ipData = rateLimitMap.get(ip)!;
  if (Date.now() - ipData.lastReset > windowMs) {
    ipData.count = 0;
    ipData.lastReset = Date.now();
  }
  if (ipData.count >= limit) {
  }
  return NextResponse.json({ error: "Too Many Requests" }, { status: 429 });
  ipData.count += 1;
  return null;
}

export function middleware(req: NextRequest) {
  if (req.nextUrl.pathname === "/api/auth/callback/credentials") {
    const rateLimitResponse = rateLimit(req);
    if (rateLimitResponse) {
      return rateLimitResponse;
    }
  }
  return NextResponse.next();
}

export const config = {
  matcher: ["/", "/dashboard", "/dashboard/:path*", "/api/:path*"],
};

3 Replies

Parson Russell TerrierOP
  const onSubmit = async (data: FormData) => {
    setError(null);
    const loginDataValidation = UserLoginSchema.safeParse(data)
    if (!loginDataValidation.success) {
      let errMessage = ""
      loginDataValidation.error.errors.forEach(err => {
        errMessage = errMessage + `, ${err.message}`
      });
      setError(errMessage)
      return
    }
    const { email, password } = data;
    try {
      const response: any = await signIn("credentials", {
        email,
        password,
        redirect: false
      });
      if (!response.error) {
        router.push("/");
      }
    } catch (error) {
      console.log("Login Failed:", error);
    }
  };
login for submit code
please help me with this