9. 미들웨어(middleware)

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
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유