Ch 05. 라우트 미들웨어로 접근 제어하기
로그인하지 않은 사용자가 마이페이지 URL을 직접 입력하면 어떻게 해야 할까요. 페이지를 보여주기 전에 먼저 확인 작업이 필요합니다. Nuxt.js의 라우트 미들웨어는 페이지가 렌더링되기 전에 실행되는 함수로, 이런 접근 제어 로직을 담기에 딱 좋은 자리입니다.
미들웨어 파일 만들기
미들웨어 파일은 middleware/ 폴더에 저장합니다. 파일명이 곧 미들웨어 이름이 됩니다.
인증 토큰을 확인해서 없으면 로그인 페이지로 보내는 미들웨어를 만들어보겠습니다.
// middleware/auth.tsexport default defineNuxtRouteMiddleware((to, from) => { const token = useCookie('auth_token') if (!token.value) { return navigateTo('/login') }})
defineNuxtRouteMiddleware()의 콜백은 두 가지 인자를 받습니다. to는 이동하려는 목적지 라우트이고, from은 현재 있는 출발지 라우트입니다.
navigateTo와 abortNavigation
미들웨어에서 라우트 이동을 제어할 때 두 가지 함수를 주로 사용합니다.
navigateTo(path)는 지정한 경로로 리다이렉트합니다. return과 함께 써야 이후 코드가 실행되지 않습니다.
// 로그인 페이지로 리다이렉트합니다.return navigateTo('/login')// 현재 히스토리를 교체하며 이동합니다.return navigateTo('/login', { replace: true })
abortNavigation()은 이동 자체를 취소합니다. 현재 페이지에 머물게 되며, 에러 메시지를 전달할 수도 있습니다.
// 이동을 중단하고 현재 페이지에 머뭅니다.return abortNavigation()// 에러 페이지로 이동합니다.return abortNavigation({ statusCode: 403, message: '접근 권한이 없습니다.' })
페이지에 미들웨어 적용하기
만든 미들웨어를 특정 페이지에 적용하려면 definePageMeta()의 middleware 속성을 사용합니다.
<!-- pages/mypage.vue -->
<script setup lang="ts">
definePageMeta({
middleware: 'auth'
})
</script>
파일명(auth.ts)에서 확장자를 뺀 이름을 문자열로 전달합니다. 여러 미들웨어를 배열로 나열할 수도 있습니다.
definePageMeta({ middleware: ['auth', 'verified']})
인라인 미들웨어
파일로 따로 만들지 않고 페이지 안에 직접 미들웨어 함수를 정의할 수도 있습니다. 한 페이지에서만 쓰는 간단한 로직에 적합합니다.
<script setup lang="ts">
definePageMeta({
middleware: defineNuxtRouteMiddleware((to, from) => {
// 이 페이지에서만 실행되는 가드 로직을 작성합니다.
const { role } = useAuthStore()
if (role !== 'admin') {
return navigateTo('/')
}
})
})
</script>
미들웨어를 잘 활용하면 인증, 권한 확인, 페이지 접근 로그 기록 등 다양한 전처리 로직을 페이지 컴포넌트와 분리해서 깔끔하게 관리할 수 있습니다.