Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set protected routes with NextJS 13?

I have been working on a website whose major component is a student and faculty login portal. Now, I have managed to generate a JWT and store it as a cookie in the browser and on successful student login, it takes you /student

However, if someone simply types /student into the URL, it still redirects. You can check out the full code down here: https://github.com/shivpreet16/event-junction

I am not sure how to set /student as a protected route so as to make it inaccessible by simply typing in the URL. I tried to Chat GPT my way through this and wrote /utils/withAuth :

import { useEffect } from 'react';
import Router from 'next/router';
import { getTokenCookie, isAuthenticated } from './auth';

const withAuth = (WrappedComponent) => {
  const Auth = (props) => {
    const token = getTokenCookie();

    useEffect(() => {
      if (!isAuthenticated()) {
        Router.push('/');
      }
    }, []);

    if (!token) {
      return null;
    }

    return <WrappedComponent {...props} />;
  };

  return Auth;
};

export default withAuth;

And during export default in /student.js, I wrote: export default withAuth(student)

However, this does not seem to recognize the withAuth function itself:

Server Error

Any idea how to work this out?

like image 362
Jayanti Avatar asked Nov 14 '25 22:11

Jayanti


2 Answers

The simplest way of doing this in Next 13 is by using Nextjs 's Middleware. All you have to do is to just create a Middleware.ts file in the root and before each page request you can check if isAuthenticated() is true or not.

import { NextRequest, NextResponse } from 'next/server';
import { isAuthenticated } from './auth';

export default function middleware(req: NextRequest) {
  const path = req.nextUrl.pathname;

  const protectedRoutes = ["/", "Route1", "Route2"];

  if (path.startsWith("/_next")) {
    return NextResponse.next();
  }

  if (!isAuthenticated() && protectedRoutes.includes(path)) {
    const httpsRedirectUrl = `${Your_URL}/login`;
    return NextResponse.redirect(httpsRedirectUrl);
  }

  return NextResponse.next();
}
like image 119
Numan Anees Avatar answered Nov 17 '25 22:11

Numan Anees


I created a function that I call inside every server component that's supposed to be protected.

protectedPage.tsx:

import { cookies } from "next/dist/client/components/headers";
import { redirect } from "next/navigation";

export default function protectedPage() {
  const cookieStore = cookies();
  const accessToken = cookieStore.get("accessToken");
  const refreshToken = cookieStore.get("refreshToken");

  if (!accessToken || !refreshToken) {
    return redirect("/auth/sign-in");
  }
}

Example usage:

export default function Test() {
  protectedPage();
  return (
    <>
      <h1>hello this is protected</h1>
    </>
  );
}
like image 42
netrolite Avatar answered Nov 17 '25 22:11

netrolite