
백오피스 도메인에서 route protect를 리팩토링 하면서 Nextjs에서 제공하는 Middleware를 사용하였다. 기존에는 어떤 문제가 있었고 이를 해결하기 위해 왜 Middleware를 선택했는지 얘기해보도록 하겠습니다!
Middleware에서 구현하기로 결정하기까지 Secure Routes에 대한 다양한 방식을 고민했습니다. 크게는 client 방식과 server 방식으로 나뉘어지고, 총 4가지의 방법이 있습니다.
4가지를 방식을 고려하면서 최종적으로 Middleware를 활용하는게 다른 방식보다 효과적이고 좋다고 느꼈습니다. Client-Side의 hooks의 방식은 기존 코드 자체를 분석하고 고치는 비용이 더 많다고 생각했으며, HOC, Server-Side로 구현할 경우도 화이트/블랙리스트를 설정하는 방식이 Middleware방식보다 장점이 없다고 느꼈습니다.
Nextjs 공식문서에서는 아래와 같이 서술하였다. 한줄로 설명하자면 nextjs에서 페이지를 렌더링하기 전에 서버 측에서 실행되는 함수이다.
Middleware allows you to run code before a request is completed. Then, based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly.
route protect의 구분하는 매개는 결국 로그인유무이다. 해당부분도 같이 리팩토링을 진행했지만, 주제가 섞여 쓸데없는 내용이 길어지므로 기회가 되면 다른글로 다루도록 하겠다. AS-IS 버전에서는 client에서 유효성을 진행하였지만, Middleware에서 로그인 유무를 체크하기 위해서 로그인 시 쿠키에 isAuthenticated key에 로그인 유무 boolean을 저장하고, Middleware에서 이 값을 보고 판단하여 로그인 유무를 체크하였다.
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(req: NextRequest) {
const response = NextResponse.next();
const isAuthenticated: boolean = JSON.parse(req.cookies.get('isAuthenticated')?.value ?? 'false');
if (req.nextUrl.pathname.includes(SIGN_IN_PATH) && isAuthenticated) {
const homeURL = new URL(HOME_PATH, req.nextUrl.origin);
return NextResponse.redirect(homeURL.toString());
}
if (!whiteListRoutes.includes(req.nextUrl.pathname) && !isAuthenticated) {
const signinURL = new URL(SIGN_IN_PATH, req.nextUrl.origin);
return NextResponse.redirect(signinURL.toString());
}
return response;
}
const SIGN_IN_PATH = '/signin';
const HOME_PATH = '/editor';
const AUTH_PATH = '/oauth';
const whiteListRoutes = [AUTH_PATH, SIGN_IN_PATH];
그렇다면 리팩토링 후 맨 위에 얘기했던 4가지 개선점이 다 해결되었을까?
useAuthenticatedUser, useAuthenticatedUserEffect 등 2가지의 custom-hooks로 관리하던 로직을 한곳에서 관리하여 응집도를 높였다.이번 리팩토링을 진행하면서 다양하게 Secure Routes를 설정할 수 있는걸 알게되어 좋았던것 같다. 또한 설정을 할 때 auth에 관해서도 연계되기 때문에 auth도 같이 리팩토링을 진행하여 좀 더 견고한 코드가 된 것 같다. 이부분은 다른 포스팅에서 다루도록하겠습니다. 😄