Search code examples
next.jsmiddleware

Why my middleware doesn't protect routes?


I am using next.js and trying to use middleware. If cookies has not token, it means there is no user, so no one should access specific page as profile. But in my case, when I dont have token and write to url /profile I am able to see profile page. Can you please tell me what I am doing wrong? Thanks

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

export async function middleware(req) {

  try {
    const path = req.nextUrl.pathname;

    const isPublicPage =
      path === '/login' || 
      path === '/register' || 
      path === '/' || 
      path === '/signOutPage';

    const token = req.cookies.userToken;
    console.log('token >>>', token);

    if (token === undefined && !isPublicPage) {

      return NextResponse.redirect(new URL('/login', req.nextUrl.href));
    }

    if (token && token.length > 15 && isPublicPage) {
      return NextResponse.redirect(new URL('http://localhost:3000/login', req.nextUrl.href));
    }

    return NextResponse.next();
  } catch (error) {
    return NextResponse.error();
  }
}

export const config = {
  matcher: ['/', '/login', '/register', '/signOutPage'],
};

UPDATE: I have to have all routes in matcher!!

Here is another issue I am facing. If user is logged in, it means there is token, so user can see profile page,but user should not see login, register page. I am getting infinitive loop in terminal..


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


export async function middleware(req) {
  try {
    const path = req.nextUrl.pathname;
   
    const isPublicPage =
      path === '/login' || 
      path === '/register' || 
      path === '/' || 
      path === '/signOutPage';

    
    const token = req.cookies.get('userToken')?.value
    console.log('token >>>', token);

    if (!token && !isPublicPage) {

      return NextResponse.redirect(new URL('/login', req.nextUrl.href));
    }

  // here is infinitive loop in terminal!
 // if I remove this if statement all is good

   if (token && isPublicPage) {
      return NextResponse.redirect(new URL('/', req.nextUrl.href));
    }

  // if I use this code all is working properly
  // but is this way ok? 

  // remove this code
  /* if (token && isPublicPage) {
      return NextResponse.redirect(new URL('/', req.nextUrl.href));
    }  */

   const hiddeLogin = 
      path === '/login' ||
      path === '/register' 

   // then

  if (token && hiddeLogin) {
      return NextResponse.redirect(new URL('/', 
    req.nextUrl.href));
    }

 // if token is there and user is trying find login page, middleware redirects him to '/' home page. is this ok ? or is there better solution? thanks 


    return NextResponse.next();
  } catch (error) {
    return NextResponse.error();
  }
}

// all routes here 
export const config = {
  matcher: ['/', '/login', '/register', '/signOutPage', '/profile'],
};


Solution

  • Your middleware is not configured for the /profile route. You can have it run on all routes using a wildcard in the matcher:

    export const config = {
      matcher: ['/:path*'],
    };
    

    You can use regular expressions to avoid matching certain paths, so you don't have to handle the excluded pages in source code. More info here.