네비게이션 가드

네비게이션 가드(navigation guard) 란 뷰 라우터로 특정 url에 접근할 때 해당 url의 접근을 막는 방법을 말한다.
예를 들어, 사용자의 인증 정보가 없으면 특정 페이지에 접근하지 못하게 할 때 사용하는 기술이다.

네비게이션 가드의 종류

  • 애플리케이션 전역에서 동작하는 전역 가드
  • 특정 url에서만 동작하는 라우터 가드
  • 라우터 컴포넌트 안에 정의하는 컴포넌트 가드

전역 가드

전역 가드는 라우터 인스턴스를 참조하는 객체로 설정할 수 있다.
router.beforeEach를 사용하여 라우트 되기 이전에 전역 등록을 할 수 있고
네비게이션이 트리거될 때마다 가드의 작성 순서에 따라 로직을 실행한다.
가드는 비동기식으로 실행되며 네비게이션은 모든 훅이 해결되기 전까지 보류 중으로 간주된다.

전역 가드 설정은 라우터 인스턴스를 생성 후 router 변수에 .beforeEach() API를 호출하면 된다.

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
  next();
})

beforeEach()를 호출하면 받는 3개의 인자

  • to : 이동할 url 정보가 담긴 라우터 객체
  • from : 현재 url 정보가 담긴 라우터 객체
  • next : to에서 지정한 url로 이동하기 위해 호출해야 하는 함수
    • next() : 그냥 다음 route 인 to로 연결
    • next(false) : to로의 이동을 중지하고 다시 from 으로 이동
    • next('/') 또는 next({ path: '/' }) : to에 대한 연결을 중지하고 지정한 path로 리디렉션
    • next(Error) : Error 객체를 전달 받으면 to로의 이동을 중지하고 router.onError() 에 등록된 콜백 수행

router.beforeEach()를 호출하면 모든 라우팅이 대기 상태가 된다.
원래 url이 변경되고 나면 해당 url에 따라 화면이 자연스럽게 전환되어야 하지만 전역 가드를 설정했기 때문에 화면이 전환되지 않는다.
여기서 해당 url로 라우팅 하기 위해서는 next()를 호출해줘야 하며 next()가 호출되기 전까지 화면이 전환되지 않는다.

Global Resolve Guards

2.5.0 이후로 router.beforeResolve를 사용하여 글로벌 가드를 등록 할 수 있다.
router.beforeEach와 유사하지만 모든 컴포넌트 가드(ex. beforeEach)와 비동기 라우트 컴포넌트를 불러온 후 네비게이션 가드를 확인하기 전에 호출된다는 차이가 있다.
data api로 부터 가져오거나 비동기적인 것들을 할때 사용하는 것이 적합하다.

Global After Hooks

router.afterEach는 전역 훅을 등록 할 수도 있지만, 이 훅은 가드와 달리 next()를 인자로 받지 않아 네비게이션에 영향을 주지 않는다.

router.afterEach((to, from) => {
  // ...
})

페이지 이동 후 분석, 페이지 제목 변경, 페이지 발표와 같은 접근성 기능 및 기타 여러 작업에 유용하다.

라우트 별 가드

beforeEnter 는 가드를 라우트의 설정 객체에 직접 정의 할 수 있다.

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

컴포넌트 내부 가드

마지막으로 beforeRouteEnterbeforeRouteLeave를 사용하여
라우트 컴포넌트(라우터 설정으로 전달되는 컴포넌트) 내부에 라우트 네비게이션 가드를 직접 정의 할 수 있다.

  • beforeRouteEnter
  • beforeRouteUpdate(2.2 버전에 추가)
  • beforeRouteLeave

beforeRouteEnter 가드는 네비게이션이 확인되기 전에 가드가 호출되기 때문에
새로운 엔트리 컴포넌트가 아직 생성되지 않아 this에 접근하지 못한다.

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 컴포넌트를 렌더링하는 라우트 전에 호출
    // 때문에 가드가 호출 될 때 아직 생성되지 않아 `this` 컴포넌트 인스턴스에 접근 할 수 없음
  }
}

그러나 콜백을 next()에 전달하여 인스턴스에 액세스 할 수 있다.
네비게이션이 확인되고 컴포넌트 인스턴스가 콜백에 전달인자로 전달 될 때 콜백이 호출된다.

beforeRouteEnter (to, from, next) {
  next(vm => {
    // `vm`을 통한 컴포넌트 인스턴스 접근
  })
}

beforeRouteLeave 안에서 this에 직접 접근 할 수 있다.
leave 가드는 일반적으로 사용자가 저장하지 않은 편집 내용을 두고 실수로 라우트를 떠나는 것을 방지하는데 사용된다. 탐색은 next(false)를 호출하여 취소할 수 있다.

const Foo = {
  template: `...`,
  beforeRouteLeave (to, from, next) {
    // 컴포넌트를 렌더링하는 라우트가 네비게이션 되기 전에 호출
    // `this` 컴포넌트 인스턴스에 접근 할 수 있음
  }
}

전체 네비게이션 시나리오

네비게이션이 트리거됨
➔ 비활성화 될 컴포넌트에서 가드를 호출
➔ 전역 beforeEach 가드 호출
➔ 재사용되는 컴포넌트에서 beforeRouteUpdate 가드 호출(2.2 이상)
➔ 라우트 설정에서 beforeEnter 호출
➔ 비동기 라우트 컴포넌트 해결
➔ 활성화된 컴포넌트에서 beforeRouteEnter 호출
➔ 전역 beforeResolve 가드 호출(2.5이상)
➔ 네비게이션 완료
➔ 전역 afterEach 훅 호출
➔ DOM 갱신 트리거 됨
➔ 인스턴스화 된 인스턴스들의 beforeRouteEnter 가드에서 next()에 전달 된 콜백을 호출


References

profile
까먹지마도토도토잠보🐘

0개의 댓글