Nuxt 는 경로가 바뀔 때 수행되는 미들웨어를 제공한다. 글로벌 미들웨어는 middleware/ 디렉터리에 .global 접미사를 가진 소스파일로 정의하고 인라인 미들웨어는 각 페이지 내 definePageMeta 유틸 함수로 정의한다.
자세한 내용은 Nuxt-Directory > middleware 을 참고한다.
도메인에 공통적으로 처리할 수 있는 미들웨어는 인증/인가 부분에서 라우팅 경로를 리다이렉션 해주는 경우를 생각해 볼 수 있다. 예를 들어 로그인 후 정해진 랜딩페이지로 리다이렉션 하거나, 로그아웃 전에 상태값을 지우거나, 자원을 초기화 하는 작업 등의 예가 있을 수 있다.
사용자 정의 미들웨어 생성
프로젝트 루트에 middleware/ 디렉토리를 생성한다. 해당 디렉토리에 auth.global.ts 파일을 생성하고 아래와 같이 코딩한다.
/middleware/auth.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
console.log(to);
console.log(from);
})
브라우저 콘솔에서 확인하기 위해서 NuxtLink 를 활용하여 메뉴 경로를 만들어 준다.
/components/Header/index.vue
<script setup lang="ts"></script>
<template>
<header>
<ul>
<li>
<NuxtLink to="/">Home</NuxtLink>
</li>
<li>
<NuxtLink to="/custom">Custom</NuxtLink>
</li>
</ul>
</header>
</template>
메인 페이지에 메뉴를 노출하자.
app.vue
<template>
<div>
<NuxtLayout>
<Header />
<NuxtPage />
</NuxtLayout>
</div>
</template>
<script setup lang="ts">
</script>
이전에 만들어 놓은 http://localhost:3000/ 페이지를 호출하고, Custom 메뉴를 호출한 후 브라우저 콘솔을 확인해 보자. 아래와 같은 to, from 에 대한 로그를 확인할 수 있다.
사용 예 : 로그인
우선 헤더 영역의 메뉴를 좀더 현실감 있게 바꿔보자.
/components/Header/index.vue
<script setup lang="ts">
</script>
<template>
<header>
<ul class="list-none m-0 p-0 overflow-hidden bg-gray-800">
<li class="float-left">
<NuxtLink to="/" class="block text-white text-center py-2 px-4 no-underline">Home</NuxtLink>
</li>
<li class="float-left">
<NuxtLink to="/Custom" class="block text-white text-center py-2 px-4 no-underline">Custom</NuxtLink>
</li>
<li class="float-left">
<NuxtLink to="/my-profile" class="block text-white text-center py-2 px-4 no-underline">MyProfile</NuxtLink>
</li>
</ul>
</header>
</template>
로그인 페이지가 필요하므로 아래와 같이 로그인 페이지를 만들자.
/pages/login.vue
<template>
<div class="bg-gray-100 flex items-center justify-center">
<div class="bg-white p-8 rounded shadow-md w-96">
<h2 class="text-2xl text-gray-700 font-bold mb-6">Login</h2>
<form action="#" method="POST">
<div class="mb-4">
<label for="email" class="block text-gray-700 text-sm font-bold mb-2">Email</label>
<input type="email" id="email" name="email" class="w-full px-3 py-2 border rounded-md"
placeholder="Enter your email" required>
</div>
<div class="mb-4">
<label for="password" class="block text-gray-700 text-sm font-bold mb-2">Password</label>
<input type="password" id="password" name="password" class="w-full px-3 py-2 border rounded-md"
placeholder="Enter your password" required>
</div>
<button type="submit"
class="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600 focus:outline-none focus:shadow-outline-blue active:bg-blue-800">
Login
</button>
</form>
</div>
</div>
</template>
<script setup lang="ts">
</script>
위 소스를 이용해서 실제 사용 예를 구성해 보자. 내 프로필 페이지는 로그인 했을 때만 접근할 수 있다고 가정할 수 있다.
로그인 되지 않았을 때는 로그인 페이지로 보내자. 현재 프로필 페이지는 아래 소스와 같다.
/pages/my-profile.vue
<template>
<div>My profile</div>
</template>
화면으로 보면 아래와 같을 것이다.
내 프로필 페이지로 접근할 때 로그인 되지 않았다면, 로그인 페이지로 리다이렉션 하기 위해 로그인 여부를 미들웨어에서 검증한다.
/middleware/auth.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
const isLoggedIn = false;
const authorizedPage = ["/my-profile"];
console.log(to.fullPath);
if (authorizedPage.includes(to.fullPath) && !isLoggedIn) {
// redirect to login page
return navigateTo("/login");
}
});
isLoggedIn 상태값은 실제 앱에서는 상태 관리자를 통해 얻어 올 수 있을 것이다. 여기서는 리다이렉션을 검증하기 위한 코드이므로 일단 하드코딩한다. 메인 페이지에서 MyProfile 메뉴를 클릭하면 /login 페이지로 리다이렉션 되는 것을 확인할 수 있다.
인라인 미들웨어
위 기능을 전역적으로 처리하지 않고, /my-profile 페이지에 접근했을 때만 처리할 수 있다. 위에서 언급한 것처럼 definePageMeta 유틸 함수를 이용하면 된다.
.global 접미사가 붙어 있는 미들웨어는 전역적으로 처리되므로 auth.global.ts 의 파일명을 auth.ts 로 바꾸고 /pages/my-profile.vue 코드를 아래와 같이 변경하자.
/pages/my-profle.ts
<script setup lang="ts">
definePageMeta({
middleware: 'auth'
});
</script>
<template>
<div>My profile</div>
</template>
메인페이지에서 MyProfile 메뉴를 클릭하면 동일하게 로그인 페이지로 이동하는 걸 볼 수 있다.
'Nuxt 개발 가이드 > 01. Set up' 카테고리의 다른 글
8. 플러그인(plugins) (1) | 2024.01.01 |
---|---|
7. 컴포저블(Composables) (0) | 2023.12.31 |
6. Assets (1) | 2023.12.31 |
5. 레이아웃(layouts) (0) | 2023.12.31 |
4. 컴포넌트 (0) | 2023.12.31 |