(쀑급) Vue.js λΌμš°ν„° λ„€λΉ„κ²Œμ΄μ…˜ κ°€λ“œ μ•Œμ•„λ³΄κΈ°

λ„€λΉ„κ²Œμ΄μ…˜ κ°€λ“œλž€?

λ„€λΉ„κ²Œμ΄μ…˜ κ°€λ“œ(navigation guard)λž€ λ·° λΌμš°ν„°λ‘œ νŠΉμ • URL에 μ ‘κ·Όν•  λ•Œ ν•΄λ‹Ή URL의 접근을 λ§‰λŠ” 방법을 λ§ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μ‚¬μš©μžμ˜ 인증 정보가 μ—†μœΌλ©΄ νŠΉμ • νŽ˜μ΄μ§€μ— μ ‘κ·Όν•˜μ§€ λͺ»ν•˜κ²Œ ν•  λ•Œ μ‚¬μš©ν•˜λŠ” κΈ°μˆ μž…λ‹ˆλ‹€.

λ„€λΉ„κ²Œμ΄μ…˜ κ°€λ“œμ˜ μ’…λ₯˜

λ„€λΉ„κ²Œμ΄μ…˜ κ°€λ“œμ˜ μ’…λ₯˜λŠ” μ•„λž˜μ™€ 같이 3κ°€μ§€κ°€ μžˆμŠ΅λ‹ˆλ‹€.

  • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „μ—­μ—μ„œ λ™μž‘ν•˜λŠ” μ „μ—­ κ°€λ“œ
  • νŠΉμ • URLμ—μ„œλ§Œ λ™μž‘ν•˜λŠ” λΌμš°ν„° κ°€λ“œ
  • λΌμš°ν„° μ»΄ν¬λ„ŒνŠΈ μ•ˆμ— μ •μ˜ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ κ°€λ“œ

μ „μ—­ κ°€λ“œ

μ „μ—­ κ°€λ“œλŠ” λΌμš°ν„° μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•˜λŠ” 객체둜 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 그러면 μ „μ—­ κ°€λ“œ μ„€μ • 방법을 μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

λ¨Όμ €, μ „μ—­ κ°€λ“œ 섀정을 μœ„ν•΄ λ¨Όμ € μ•„λž˜μ™€ 같이 λΌμš°ν„° μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

var router = new VueRouter();

λ‹€μŒμœΌλ‘œ router λ³€μˆ˜μ— μ•„λž˜μ™€ 같이 .beforeEach() APIλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.

router.beforeEach(function (to, from, next) {
  // to : 이동할 url
  // from : ν˜„μž¬ url
  // next : toμ—μ„œ μ§€μ •ν•œ url둜 μ΄λ™ν•˜κΈ° μœ„ν•΄ κΌ­ ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ” ν•¨μˆ˜
});

μ—¬κΈ°μ„œ beforeEach()λ₯Ό ν˜ΈμΆœν•˜λ©΄ λ‹€μŒκ³Ό 같이 3개의 인자λ₯Ό λ°›μŠ΅λ‹ˆλ‹€.

  • to : 이동할 url 정보가 λ‹΄κΈ΄ λΌμš°ν„° 객체
  • from : ν˜„μž¬ url 정보가 λ‹΄κΈ΄ λΌμš°ν„° 객체
  • next : toμ—μ„œ μ§€μ •ν•œ url둜 μ΄λ™ν•˜κΈ° μœ„ν•΄ κΌ­ ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ” ν•¨μˆ˜

router.beforeEach()λ₯Ό ν˜ΈμΆœν•˜κ³  λ‚˜λ©΄ λͺ¨λ“  λΌμš°νŒ…μ΄ λŒ€κΈ° μƒνƒœκ°€ λ©λ‹ˆλ‹€. μ›λž˜ url이 λ³€κ²½λ˜κ³  λ‚˜λ©΄ ν•΄λ‹Ή url에 따라 화면이 μžμ—°μŠ€λŸ½κ²Œ μ „ν™˜λ˜μ–΄μ•Ό ν•˜λŠ”λ° μ „μ—­ κ°€λ“œλ₯Ό μ„€μ •ν–ˆκΈ° λ•Œλ¬Έμ— 화면이 μ „ν™˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ„œ ν•΄λ‹Ή url둜 λΌμš°νŒ… ν•˜κΈ° μœ„ν•΄μ„œλŠ” next()λ₯Ό ν˜ΈμΆœν•΄μ€˜μ•Ό ν•©λ‹ˆλ‹€. next()κ°€ 호좜되기 μ „κΉŒμ§€ 화면이 μ „ν™˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ „μ—­ κ°€λ“œ λ™μž‘ 예제

μ•žμ—μ„œ μ„€λͺ…ν•œ μ „μ—­ κ°€λ“œμ˜ λ™μž‘ 방식을 μ΄ν•΄ν•˜κΈ° μœ„ν•΄ μ•„λž˜μ™€ 같은 λΌμš°ν„° μ½”λ“œλ₯Ό μ€€λΉ„ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

// λΌμš°ν„° μ»΄ν¬λ„ŒνŠΈ
var Login = { template: '<p>Login Component</p>' };
var Home = { template: '<p>Home Component</p>' };

// λΌμš°νŒ… 정보
var router = new VueRouter({
  routes: [
    { path: '/login', component: Login },
    { path: '/home', component: Home }
  ]
});

전체 μ‹€ν–‰ μ½”λ“œ 확인 - jsfiddle

μœ„ μ½”λ“œμ˜ μ‹€ν–‰ κ²°κ³ΌλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

λ·° κΈ°λ³Έ λΌμš°ν„° 예제

μ—¬κΈ°μ„œ μ „μ—­ κ°€λ“œλ₯Ό μ„€μ •ν•˜λŠ” μ½”λ“œλ₯Ό μ•„λž˜μ™€ 같이 μΆ”κ°€ν•©λ‹ˆλ‹€.

router.beforeEach(function (to, from, next) {
  console.log('every single routing is pending');
});

이제 β€˜/loginβ€™μ΄λ‚˜ β€˜/homeβ€™μœΌλ‘œ μ΄λ™ν•˜λ”λΌλ„ λΌμš°νŒ…μ΄ λ˜μ§€ μ•Šκ³  μ•„λž˜μ™€ 같이 둜그만 좜λ ₯λ©λ‹ˆλ‹€.

μ „μ—­ κ°€λ“œ μ„€μ • λ•Œλ¬Έμ— νŽ˜μ΄μ§€λŠ” μ΄λ™ν•˜μ§€ μ•Šκ³  λŒ€μ‹  둜그만 좜λ ₯ν•˜λŠ” ν™”λ©΄

λ§Œμ•½ μ›ν•˜λŠ” url둜 μ΄λ™ν•˜κ³  μ‹ΆμœΌλ©΄ μ•„λž˜μ™€ 같이 next()λ₯Ό ν˜ΈμΆœν•˜λ©΄ λ©λ‹ˆλ‹€.

router.beforeEach(function (to, from, next) {
  next();
});

μ „μ—­ κ°€λ“œλ‘œ νŽ˜μ΄μ§€ μΈμ¦ν•˜κΈ°

μ „μ—­ κ°€λ“œλ₯Ό μ‹€μ œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‘œμ§μ— μ–΄λ–»κ²Œ μ μš©ν•  수 μžˆλŠ”μ§€ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€. μ•žμ—μ„œ μ‚΄νŽ΄λ³Έ 예제의 Login μ»΄ν¬λ„ŒνŠΈμ— λ‹€μŒκ³Ό 같이 meta 정보λ₯Ό μΆ”κ°€ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

var router = new VueRouter({
  routes: [
    // meta 정보에 authRequiredλΌλŠ” Boolean κ°’ μΆ”κ°€
    { path: '/login', component: Login, meta: {authRequired: true} },
    { path: '/home', component: Home }
  ]
});

그리고 beforeEach()의 콜백 ν•¨μˆ˜μ— μ‚¬μš©μž 인증 μ—¬λΆ€λ₯Ό μ²΄ν¬ν•˜λŠ” λ‘œμ§μ„ μΆ”κ°€ν•©λ‹ˆλ‹€.

router.beforeEach(function (to, from, next) {
  // to: 이동할 url에 ν•΄λ‹Ήν•˜λŠ” λΌμš°νŒ… 객체
  if (to.matched.some(function(routeInfo) {
    return routeInfo.meta.authRequired;
  })) {
    // 이동할 νŽ˜μ΄μ§€μ— 인증 정보가 ν•„μš”ν•˜λ©΄ κ²½κ³  창을 λ„μš°κ³  νŽ˜μ΄μ§€ μ „ν™˜μ€ ν•˜μ§€ μ•ŠμŒ
    alert('Login Please!');
  } else {
    console.log("routing success : '" + to.path + "'");
    next(); // νŽ˜μ΄μ§€ μ „ν™˜
  };
});

μœ„ μ½”λ“œλŠ” μ΄λ™ν•˜λ €λŠ” νŽ˜μ΄μ§€μ— λ§Œμ•½ 인증 정보가 ν•„μš”ν•˜λ©΄ κ²½κ³  창을 λ„μš°κ³  화면은 μ „ν™˜ν•˜μ§€ μ•ŠλŠ” μ½”λ“œμž…λ‹ˆλ‹€. λ·° λΌμš°ν„° μΈμŠ€ν„΄μŠ€μ—μ„œ β€˜/login’에 ν•΄λ‹Ήν•˜λŠ” λΌμš°ν„° κ°μ²΄μ—λ§Œ authRequired 값을 섀정해놨기 λ•Œλ¬Έμ— β€˜/home’ νŽ˜μ΄μ§€λ‘œ 이동할 λ•ŒλŠ” next()둜 νŽ˜μ΄μ§€λ₯Ό 이상 없이 μ „ν™˜ν•©λ‹ˆλ‹€. μœ„ μ½”λ“œλ₯Ό μ‹€ν–‰ν•œ κ²°κ³ΌλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

인증 값이 ν•„μš”ν•œ νŽ˜μ΄μ§€λŠ” λΌμš°νŒ…μ„ λ§‰λŠ” ν™”λ©΄

μœ„ μ˜ˆμ œμ—μ„œ μ‚¬μš©ν•œ .some()은 μžλ°”μŠ€ν¬λ¦½νŠΈ λ‚΄μž₯ APIμž…λ‹ˆλ‹€. μ§€μ •λœ λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œλ₯Ό κ²€μ‚¬ν•˜μ—¬ 쑰건을 λ§Œμ‘±μ‹œν‚€λ©΄ true 값을 λ°˜ν™˜ν•˜κ³ , μ•„λ‹ˆλ©΄ false 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

λΌμš°ν„° κ°€λ“œμ™€ μ»΄ν¬λ„ŒνŠΈ κ°€λ“œ

μ•žμ—μ„œ μ‚΄νŽ΄λ³Έ μ „μ—­ κ°€λ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ λΌμš°ν„° κ°€λ“œμ™€ μ»΄ν¬λ„ŒνŠΈ κ°€λ“œλ„ 같은 μ›λ¦¬λ‘œ λ™μž‘ν•©λ‹ˆλ‹€. λ‹€λ§Œ URL 이동을 막기 μœ„ν•΄ μ‚¬μš©ν•˜λŠ” API만 쑰금 λ‹€λ¦…λ‹ˆλ‹€.

λΌμš°ν„° κ°€λ“œ

전체 λΌμš°νŒ…μ΄ μ•„λ‹ˆλΌ νŠΉμ • λΌμš°νŒ…μ— λŒ€ν•΄μ„œ κ°€λ“œλ₯Ό μ„€μ •ν•˜λŠ” 방법은 μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

var router = new VueRouter({
  routes: [
    {
      path: '/login',
      component: Login,
      beforeEnter: function(to, from, next) {
        // 인증 κ°’ 검증 둜직 μΆ”κ°€
      }
    }
  ]
})

μ»΄ν¬λ„ŒνŠΈ κ°€λ“œ

λΌμš°ν„°λ‘œ μ§€μ •λœ νŠΉμ • μ»΄ν¬λ„ŒνŠΈμ— κ°€λ“œλ₯Ό μ„€μ •ν•˜λŠ” 방법은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

const Login = {
  template: '<p>Login Component</p>',
  beforeRouteEnter (to, from, next) {
    // Login μ»΄ν¬λ„ŒνŠΈκ°€ 화면에 ν‘œμ‹œλ˜κΈ° 전에 μˆ˜ν–‰λ  둜직
    // Login μ»΄ν¬λ„ŒνŠΈλŠ” 아직 μƒμ„±λ˜μ§€ μ•Šμ€ μ‹œμ 
  },
  beforeRouteUpdate (to, from, next) {
    // 화면에 ν‘œμ‹œλœ μ»΄ν¬λ„ŒνŠΈκ°€ 변경될 λ•Œ μˆ˜ν–‰λ  둜직
    // `this`둜 Login μ»΄ν¬λ„ŒνŠΈλ₯Ό μ ‘κ·Όν•  수 있음
  },
  beforeRouteLeave (to, from, next) {
    // Login μ»΄ν¬λ„ŒνŠΈλ₯Ό 화면에 ν‘œμ‹œν•œ url 값이 λ³€κ²½λ˜κΈ° μ§μ „μ˜ 둜직
    // `this`둜 Login μ»΄ν¬λ„ŒνŠΈλ₯Ό μ ‘κ·Όν•  수 있음
  }
}

글보닀 더 μ‰½κ²Œ λ°°μš°λŠ” 온라인 κ°•μ˜

μ’€ 더 μΉœμ ˆν•˜κ³  μƒμ„Έν•œ μ„€λͺ…을 μ›ν•˜μ‹ λ‹€λ©΄ μ•„λž˜ κ°•μ’Œλ₯Ό μ΄μš©ν•΄λ³΄μ‹œλŠ” 것도 쒋을 것 κ°™μ•„μš” πŸ˜„

μΈν”„λŸ° 온라인 κ°•μ˜ : Vue.js μ‹œμž‘ν•˜κΈ° / Vue.js 쀑급 / Vue.js μ™„λ²½ κ°€μ΄λ“œ
μΈν”„λŸ° 온라인 κ°•μ˜ : Vue.js 끝μž₯λ‚΄κΈ° / ν”„λŸ°νŠΈμ—”λ“œ 개발자λ₯Ό μœ„ν•œ μ›ΉνŒ© / PWA μ‹œμž‘ν•˜κΈ°
μΈν”„λŸ° 온라인 κ°•μ˜ : νƒ€μž…μŠ€ν¬λ¦½νŠΈ μž…λ¬Έ / μ‹€μ „ ν”„λ‘œμ νŠΈλ‘œ λ°°μš°λŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈ / Vue.js + TypeScript μ™„λ²½ κ°€μ΄λ“œ