네비게이션 가드
네비게이션 가드는 주로 탐색을 리디렉션하거나 취소하여 탐색을 막는데 사용된다.
주로 사용자의 권한과 인증 정보를 확인하여 특정 페이지에 접근하지 못하게 할 때 사용한다.
가드 연결 방법은 전역, 경로별, 컴포넌트 내부가 있다.
1. 전역으로 연결하기
비포 가드
beforeEach() : 라우터 인스턴스의 beforeEach() 메서드에 콜백함수를 전달하여, 비포 가드를 전역으로 등록할 수 있다.
탐색이 트리거 될 때마다 등록 순서대로 비포 가드가 호출된다.
가드는 비동기식으로 해결될 수 있고 탐색은 모든 훅이 해결되기 전까지 대기중으로 간주한다.
const router = createRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
return false
})
beforeEach()는 두 개의 인자를 받는다
to : 탐색될 경로 위치 객체
from : 탐색 전 현재 경로 위치 객체
beforeEach()는 선택적으로 세 번째 인자를 받는다
next : to에서 지정한 url로 이동하기 위해 꼭 호출해야 하는 함수
이건 선택적으로 다음 값 중 하나를 반환 가능
false : 현재 탐색을 취소한다.
경로 위치 정보 : router.push() 를 사용할 때 처럼 경로 위치(문자열 또는 객체)를 전달한다. 현재 탐색이 중단되고, 기존 from 위치에서 새로운 탐색 동작이 생성된다.
from : url이 변경된 경우, 해당 경로로 url이 재설정된다.
error : 예외 상황시 error를 던진다. 탐색은 취소되고 router.onError() 메서드에 전달돼 등록된 모든 콜백함수를 호출한다.
undefined, true, 아무것도 반환되지 않으면 탐색이 유효하다고 판단하여 다음 탐색 가드가 호출된다.
(1) Admin 페이지 routes 설정
const routes = [
{
path: '/admin',
name: 'Admin',
meta: { authorization: ['admin'] },
component: admin,
},
]
(2) beforeEach로 탐색 전에 권한을 확인
router.beforeEach(async (to, from, next) => {
// 가려는 곳의 권한 가져오기
const authorization = to.meta?.authorization || [];
// 이동하려는 페이지에 권한 정보가 없는 경우 그냥 이동하세요~
if (!Array.isArray(authorization) || authorization.length === 0) {
return next();
}
// admin 권한이 있는지 확인
if (authorization.includes('admin')) {
// 권한이 일치하는 경우 가세요~
return next({ name: 'Admin' });
} else {
// 권한 없을 시
return next({
name: 'NotFound',
params: { message: '권한이 없습니다.' },
});
}
}
리졸브 가드
beforeResolve() : beforeEach와 유사하지만 컴포넌트 내 가드 및 비동기 경로 컴포넌트가 모두 해결된 후, 최종적으로 탐색을 진행할 것인지 결정하기 위한 목적으로 호출된다.
탐색 후 훅
afterEach() : next함수를 전달받지 않으며 탐색에 영향을 줄 수 없음.
가드 내 전역 인젝션
inject() : 가드 내에서 사용할 수 있음.
2. 경로 별로 연결하기
라우터 가드
beforeEnter : 경로를 구성하는 객체에 직접 정의.
const routes = [
{
path: '/users/:id',
component: UserDetails,
beforeEnter: (to, from) => {
// 경로 진입 거부
return false
},
},
]
경로에 진입할 때만 가드를 실행하며 경로에 진입할 때만 가드를 실행하며 다른 경로에서 탐색된 경우에만 실행된다.
(/users/2 에서 /users/3 으로 이동)
3. 컴포넌트 내부에 연결하기
컴포넌트 가드
경로 컴포넌트 내에서 경로 탐색 가드를 직접 정의할 수 있음.
const UserDetails = {
template: ...,
beforeRouteEnter(to, from) {
// ...
},
beforeRouteUpdate(to, from) {
// ...
},
beforeRouteLeave(to, from) {
// ...
},
}
beforeRouteEnter() : 해당 컴포넌트를 렌더링 하는 경로가 결정되기 전에 호출. 그래서 컴포넌트 인스턴스가 아직 생성이 안되서 this 사용 불가. 근데 next에 콜백을 전달하여 접근할 수 있음. 유일하게 next 전달이 가능
beforeRouteUpdate() : 해당 컴포넌트를 렌더링 하는 경로의 세부 정보가 변경될 때 동일한 컴포넌트가 사용되는 경우. /user/:id 경로에서 /users/1과 /users/2 사이를 탐색할 경우 호출됨. 이미 마운트도니 상태이므로 this 사용 가능
beforeRouteLeave() : 해당 컴포넌트 경로를 떠나려고 할 때 호출. this. 사용 가능. 실수로 경로를 떠나는 것을 방지하는데 사용된다.
참고 사이트
라우터 네비게이션 가드 문서
https://router.vuejs.org/guide/advanced/navigation-guards.html
캡틴판교님 블로그
https://joshua1988.github.io/web-development/vuejs/vue-router-navigation-guards/
'🧠 저장 > Vue' 카테고리의 다른 글
v-bind와 v-model의 간단 차이점 (0) | 2024.01.27 |
---|---|
vue2 watch와 computed의 차이점 (0) | 2024.01.24 |
컴포넌트 디자인 패턴 (common, slot, controlled, renderless) 간단 정리 (0) | 2024.01.12 |
mixin 간단 정리 (0) | 2024.01.09 |
하이오더컴포넌트(HOC) 간단 정리 (0) | 2024.01.03 |