next.js에는 middleware.ts라는 파일이 있다.
이 middleware.ts 파일은 클라이언트가 서버로 요청을 보낼 때,
중간에서 요청을 가로채서 적절한 처리를 해준 뒤 서버로 전달해주는 역할을 한다.
따라서 보통 middleware.ts 파일의 용도는
1) 전역 미들웨어: 모든 요청에 적용되는 미들웨어로, 보안, 로깅 등과 같은 전반적인 기능을 처리한다.
2) 라우트 미들웨어: 클라이언트의 특정 pathname만 protected Route에 접근할 수 있도록 한다.
3) 보안 미들웨어: 보안에 관련된 기능을 처리하는 미들웨어로, CSRF(Cross-Site-Request-Forgery) 공격방지, XSS(Cross-Site-Scripting) 방어, 헤더 보안 설정 등을 수행할 수 있다.
4) 세션 미들웨어: 세션 관리에 사용되는 미들웨어로, 사용자의 세션을 추적하고 관리, 세션 유지를 위한 쿠키설정, 세션 저장 연동 등을 수행할 수 있다.
나는 라우트 보호를 위해 middleware.ts 파일을 작성했다.
import { createMiddlewareClient } from "@supabase/auth-helpers-nextjs";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export async function middleware(req: NextRequest) {
const res = NextResponse.next();
const supabase = createMiddlewareClient({ req, res });
const { data } = await supabase.auth.getSession();
const { data: userResults, error } = await supabase
.from("survey")
.select("*")
.eq("user_id", data.session?.user.id);
if (
!data.session &&
!req.nextUrl.pathname.startsWith("/login") &&
!req.nextUrl.pathname.startsWith("/product") &&
!(req.nextUrl.pathname === "/")
) {
return NextResponse.redirect(new URL("/login", req.url));
}
if (data.session && req.nextUrl.pathname.startsWith("/login")) {
return NextResponse.redirect(new URL("/", req.nextUrl.origin));
}
if (
data.session &&
userResults?.length !== 0 &&
req.nextUrl.pathname.startsWith("/survey")
) {
return NextResponse.redirect(new URL("/", req.nextUrl.origin));
} else {
return res;
}
}
export const config = {
matcher: [
/*
* Match all request paths "except for" the ones starting with:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
"/((?!_next/static|_next/image|favicon.ico).*)",
],
};
- 코드가 꽤 길지만,
1) 로그인을 하지 않은 사용자가 로그인과 홈 페이지 외의 다른 페이지로 접근하고자 한다면 로그인 페이지로
2) 로그인을 한 사용자가 로그인 페이지로 간다면 홈 페이지로
3) 설문조사하는 로직이 있는데, 이미 설문조사를 한 유저는 다시 설문조사 페이지를 방문하지 못하도록
하는 조건의 미들웨어다.
그런데 문제가 뭐였냐면!
로그인을 하지 않은 상태에서는 홈 페이지의 이미지가 보이지 않았고,
로그인을 해야만 홈 페이지의 이미지가 보여졌다.
도대체 문제가 뭐지?
matcher가 문제인가 싶어서 matcher를 봤더니
현재 matcher는 "정적 페이지, next 이미지, favicon 빼고 다" 이 미들웨어를 거친다.
음? 그러면 이미지는 이 미들웨어를 거치지 않는데 왜 로그인을 하지 않으면 안 나오지??
한참을 고민했다.
답은... 바롭..... 이미지가 next_image가 아니라 png 파일이었던 것이다^^^^^^^^
하...
export const config = {
matcher: [
/*
* Match all request paths "except for" the ones starting with:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
"/((?!_next/static|_next/image|favicon.ico|.*\\.png$).*)",
],
};
결국 정규식에 png 파일을 이렇게 추가를 했고...
홈 페이지에서도 이미지가 잘 나왔다.
비록 간단한 문제이긴 했지만, middleware.ts 파일에 대해서 많은 고민을 해볼 수 있었다.
다들.. middleware matcher 조심^^ 정규식 공부하자.
'TIL' 카테고리의 다른 글
2024.03.29 TIL #indexOf_vs_findIndex #문자열나누기_프로그래머스 (0) | 2024.03.30 |
---|---|
2024.03.28 TIL #기획회의 (1) | 2024.03.28 |
2024.03.18 TIL #Navigate_to #CSR_metadata #every (0) | 2024.03.18 |
2024.03.13 TIL #tanstack_Query_SSR_QueryClient_Dehydration (4) | 2024.03.14 |
2024.03.11 TIL #new RegExp() #Next.js_SSR_vs_CSR (0) | 2024.03.11 |