# Middleware

Nuxtμ—μ„œ 미듀웨어(Middleware)λŠ” νŽ˜μ΄μ§€λ‚˜ λ ˆμ΄μ•„μ›ƒμ΄ λ Œλ”λ§ 되기 전에 ν˜ΈμΆœλ˜λŠ” μ»€μŠ€ν…€ ν›…(Hook)μž…λ‹ˆλ‹€. λ―Έλ“€μ›¨μ–΄μ˜ λŒ€ν‘œμ μΈ νŠΉμ§•μ€ μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

  • Vue μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜κΈ° 전에 ν˜ΈμΆœλ˜λŠ” asyncData 보닀 더 일찍 ν˜ΈμΆœλ©λ‹ˆλ‹€(Nuxt 라이프 싸이클 μ°Έμ‘°).
  • asyncData와 λ§ˆμ°¬κ°€μ§€λ‘œ contextλ₯Ό 인자둜 λ°›κΈ° λ•Œλ¬Έμ— store, route, params, query, redirect 등에 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μœ„μ˜ 두 νŠΉμ§•λ“€μ„ ν™œμš©ν•˜μ—¬ λ„€λΉ„κ²Œμ΄μ…˜ κ°€λ“œ ν˜•νƒœλ‘œ 미듀웨어 μ œμž‘μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

WARNING

Nuxt의 또 λ‹€λ₯Έ 미듀웨어인 μ„œλ²„ 미듀웨어(serverMiddleware) (opens new window)λŠ” 이 νŽ˜μ΄μ§€μ—μ„œ 닀루고 μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

TIP

μ„œλ²„ 미듀웨어와 κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄μ„œ ν•΄λ‹Ή νŽ˜μ΄μ§€μ— λ‹€λ£¨λŠ” 미듀웨어λ₯Ό 라우트(Route) 미듀웨어라고 λΆ€λ¦…λ‹ˆλ‹€.

# μ’…λ₯˜

λ―Έλ“€μ›¨μ–΄λŠ” νŠΉμ • νŽ˜μ΄μ§€λ‚˜ λ ˆμ΄μ•„μ›ƒμ— μ’…μ†λ˜λŠ”μ§€μ— λ”°λΌμ„œ 읡λͺ… 미듀웨어와 λ„€μž„λ“œ λ―Έλ“€μ›¨μ–΄λ‘œ λ‚˜λ‰©λ‹ˆλ‹€.

# 읡λͺ… 미듀웨어(Anonymous Middleware)

읡λͺ… λ―Έλ“€μ›¨μ–΄λŠ” νŠΉμ • νŽ˜μ΄μ§€λ‚˜ λ ˆμ΄μ•„μ›ƒμ— μ’…μ†λ˜λŠ” 미듀웨어λ₯Ό λœ»ν•©λ‹ˆλ‹€. νŽ˜μ΄μ§€λ‚˜ λ ˆμ΄μ•„μ›ƒμ—μ„œ 직접 middleware 훅을 톡해 λͺ…μ‹œν•˜κΈ° λ•Œλ¬Έμ— λ‹€λ₯Έ νŽ˜μ΄μ§€λ‚˜ λ ˆμ΄μ•„μ›ƒμ—μ„œ κ³΅μœ ν•  수 μ—†μŠ΅λ‹ˆλ‹€.




Β 
Β 
Β 
Β 
Β 




// pages/secret.vue λ˜λŠ” layouts/authenticated.vue
<script>
  export default {
    middleware({ store, redirect }) {
      // λ§Œμ•½ μœ μ €κ°€ 인증 받지 λͺ»ν•œ 경우 둜그인 νŽ˜μ΄μ§€λ‘œ μ΄λ™ν•©λ‹ˆλ‹€.
      if (!store.state.authenticated) {
        return redirect("/login");
      }
    },
  };
</script>

# λ„€μž„λ“œ 미듀웨어(Named Middleware)

λ„€μž„λ“œ λ―Έλ“€μ›¨μ–΄λŠ” μ—¬λŸ¬ νŽ˜μ΄μ§€λ‚˜ λ ˆμ΄μ•„μ›ƒμ—μ„œ 곡유될 수 μžˆλ„λ‘ middleware λ””λ ‰ν† λ¦¬μ—μ„œ 파일둜 κ΄€λ¦¬λ˜λŠ” 미듀웨어듀을 λœ»ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 미듀웨어듀은 Nuxt ν™˜κ²½ νŒŒμΌμ„ 톡해 μ „μ—­μ μœΌλ‘œ μ μš©ν•˜κ±°λ‚˜ λ°˜λŒ€λ‘œ 각각의 νŽ˜μ΄μ§€λ‚˜ λ ˆμ΄μ•„μ›ƒμ„ 톡해 μ„ λ³„μ μœΌλ‘œ 적용 κ°€λŠ₯ν•©λ‹ˆλ‹€.

TIP

middleware λ””λ ‰ν† λ¦¬μ—μ„œ κ΄€λ¦¬λ˜λŠ” 파일의 이름이 λ―Έλ“€μ›¨μ–΄μ˜ 이름이 되기 λ•Œλ¬Έμ— λ„€μž„λ“œ 미듀웨어라고 λΆ€λ¦…λ‹ˆλ‹€.

μ•„λž˜ μ½”λ“œλŠ” μ „μ—­ μ„€μ •κ³Ό 지역 μ„€μ •μ˜ μ˜ˆμ‹œ μ½”λ“œμ—μ„œ μ°Έμ‘°ν•  λ„€μž„λ“œ λ―Έλ“€μ›¨μ–΄μ˜ μ˜ˆμ‹œμž…λ‹ˆλ‹€.

// middleware/stats.js
import http from "http";

export default function({ route }) {
  return http.post("http://my-stats-api.com", {
    url: route.fullPath,
  });
}

# μ „μ—­ μ„€μ •

router.middleware의 값에 μ μš©ν•˜κ³  싢은 λ―Έλ“€μ›¨μ–΄μ˜ 이름을 λ¬Έμžμ—΄ λ˜λŠ” λ¬Έμžμ—΄μ˜ λ°°μ—΄ ν˜•νƒœλ‘œ μ§€μ •ν•˜λ©΄ λͺ¨λ“  λΌμš°νŒ…μ— λŒ€ν•΄μ„œ ν•΄λ‹Ή 미듀웨어가 μž‘λ™ν•©λ‹ˆλ‹€.

// nuxt.config.js
export default {
  router: {
    // λͺ¨λ“  λΌμš°νŒ…μ— λŒ€ν•΄μ„œ stats 미듀웨어가 μ μš©λ©λ‹ˆλ‹€.
    middleware: "stats",
  },
};

# 지역 μ„€μ •

미듀웨어λ₯Ό μ μš©ν•˜κ³  싢은 νŽ˜μ΄μ§€λ‚˜ λ ˆμ΄μ•„μ›ƒμ— ν•΄λ‹Ή 미듀웨어λ₯Ό λͺ…μ‹œν•©λ‹ˆλ‹€.

// pages/index.vue λ˜λŠ” layouts/default.vue
export default {
  // μ „μ—­ μ„€μ •μ²˜λŸΌ middleware: "stats"도 κ°€λŠ₯ν•©λ‹ˆλ‹€.
  middleware: ["stats"],
};

# ν™œμš©λ²• μ˜ˆμ‹œ

μ•„λž˜μ˜ μ˜ˆμ‹œλ“€μ€ λ„€λΉ„κ²Œμ΄μ…˜ κ°€λ“œμ²˜λŸΌ μ‚¬μš©ν•  수 μžˆλŠ” 미듀웨어 ν™œμš©λ²•μž…λ‹ˆλ‹€.

# 인증

인증을 받지 λͺ»ν•œ 경우 둜그인 νŽ˜μ΄μ§€λ‘œ λ¦¬λ‹€μ΄λ ‰νŠΈ μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

// middleware/auth.vue
export default function({ store, redirect }) {
  if (!store.state.auth) {
    return redirect("/login");
  }
}

# λ‘œμΌ€μΌ

언어별 컨텐츠λ₯Ό 지원할 경우 찾고자 ν•˜λŠ” μ–Έμ–΄κ°€ 없을 λ•Œ 404 νŽ˜μ΄μ§€λ‘œ 폴백(Fallback)이 일어날 수 μžˆμŠ΅λ‹ˆλ‹€. λ‘œμΌ€μΌ 미듀웨어λ₯Ό ν™œμš©ν•˜λ©΄ 404 폴백을 막고 κΈ°λ³Έ μ–Έμ–΄ μ»¨ν…μΈ λ‘œ λ¦¬λ‹€μ΄λ ‰νŠΈ μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

// μ§€μ›λ˜λŠ” λ‘œμΌ€μΌ ν•­λͺ©
const SUPPORTED_LOCALES = ["ko-kr", "en-us", "en-de"];

export default function({ route, redirect }) {
  const { language, pageName, country } = route.params;
  const locale = `${language}-${country}`;

  if (SUPPORTED_LOCALES.includes(locale)) return;

  // ν˜„μž¬ λ‘œμΌ€μΌμ΄ μ§€μ›λ˜λŠ” λ‘œμΌ€μΌμ΄ 아닐 경우 en-us의 μ½˜ν…μΈ λ‘œ λ¦¬λ‹€μ΄λ ‰νŠΈ
  const redirectRoute = `en/us/${pageName}`;
  redirect(redirectRoute);
}

# 참고 자료