Client Side Route Cache때문에 일어나는 일

문제점

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

const AFTER_LOGIN_DOMAIN = ['/mydashboard', '/dashboard', '/mypage'] satisfies readonly string[];
const BEFORE_LOGIN_DOMAIN = ['/faq', '/privacy', '/login', '/signup', '/'] satisfies readonly string[];

export const middleware = async (request: NextRequest) => {
  const cookieStore = await cookies();
  const accessToken = cookieStore.get('accessToken');

  const pathname = request.nextUrl.pathname;
  
  if (!accessToken?.value) {
    if (AFTER_LOGIN_DOMAIN.some((path) => pathname.startsWith(path))) {
      return NextResponse.redirect(new URL('/login', request.url));
    }
  } else {
    if (BEFORE_LOGIN_DOMAIN.includes(pathname)) {
      return NextResponse.redirect(new URL('/mydashboard', request.url));
    }
  }

  return NextResponse.next();
};

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

  1. 로그인이후 로그인이 필요한 아무 페이지나 직접 접속 혹은 새로고침
    1. 이때 루트 페이지는 프리패칭됨 (사이드바 상단에 노출되어있는 Link태그때문에)
    2. 프리패칭 요청이 미들웨어를 탐
    3. 이렇게 프리칭된 데이터는 mydashboard
      1. 프리패칭을 할 당시에는 쿠키가 있기 때문에
      2. 그래서 미들웨어에서 토큰이 있다는 분기쪽으로 빠지고, mydashboard로 리다이렉션을 하게됨
  2. 로그아웃버튼을 누름
    1. 쿠키는 삭제됨
    2. 이제 router.replace로 루트페이지로 이동을 하는데
    3. 프리패치된 루트페이지가 브라우저 캐시에 있어서, 서버에 요청이 가지 않음 (미들웨어에서 콘솔이 아예 안찍힘, 관련공식 문서 내용 링크 첨부)
    4. 결국 미들웨어를 다시 한번 체크할 수 있으면 게임끝이지만, 이걸 안하고 캐시를 사용해서 문제가 발생
    5. 프래패치되어 캐시에 있는 루트페이지 랜더링 결과물을 랜더링하게 되고, 이 결과물은 mydashboard임.
  3. mydashboard로 오게됨
    1. 오게되는건 아니고, mydashboard를 틀어줌이 맞는 표현일까
    2. 아무튼 서버로 페이지 요청이 없고 캐시를 통해서 클라이언트 브라우저단에서 화면이 변함

발견한 또다른 케이스

  1. ‘/login’ 페이지로 처음 접속을 했을경우(로그인상태가 아닐때)
  2. 로그인 화면의 상단의 로고 컴포넌트가 Link컴포넌트이면서 경로가 루트이다.
  3. 루트가 프리패칭된다.