본문 바로가기

3.구현/HTML5&Javascript

[vue2] Router 활용한 접근제어

vue.js의 router를 사용해서 URL을 통한 접근제어하는 처리하는 방식을 간단하게 살펴보자.

작성자: ospace114@empal.com, http://ospace.tistory.com/

Router를 사용한 접근제어

Router에서 사용할 수 있는 접근제어 방식은 아래와 같다.

  • 전역 가드
  • 라우트별 가드
  • 컴포넌트 가드

전역가드

전체 접근에 대한 제어를 제공한다. 해당 훅은 beforeEach을 사용한다. 추가로 2.5.0 이후에는 beforeResolve을 사용할 수도 있다. 차이점은 컴포넌트별 가드와 라우트별 가드를 실행한 후에 호출된다.

const router = new VueRouter(...);

router.beforeEach( (to, from, next)=> {
    //...
    next(); // 문제가 없다면 요청 라우트로 이동
});

afterEach도 가능하지만, next가 없기 때문에 다른 경로로 이동할 수는 없다.

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

라우트별 가드

경로별 접근 제어를 제공한다. beforeEnter를 사용한다.

routes: [
    {
        path: '/foo/:name',
        name: 'foo',
        component: () => import('@/components/Foo.vue'),
        beforeEnter: (to, from, next) => {
            //...
            next();
        },
    },
],

컴포넌트 가드

컴포넌트에서 사용하는 가드인데, 총 3가지가 사용된다. beforeRouteEnter와 beforeRouteLeave이고 v2.2이후에는 beforeRouteUpdate도 사용가능하다.

cost Foo = {
    template: '...',
    beforeRouteEnter: (to, from, next) {
        // 렌더링 전 호출, 아직 생성 전이기에 this 사용 불가
        // this 대신에 vm 사용해서 컴포넌트 인스탄스 접근 가능
        next(vm=>{
            //...
        });
    },
    beforeRouteLeave: (to, from, next) {
        // 렌더링하는 라우트가 이전으로 네비게이션할 때 호출
        // this 사용 가능. 사용자가 편집 이동 방지에 사용 가능: next(false)로 이동 불가.
    }
};

간단한 사용

각 호출 파라미터 의미는 다음과 같다.

  • to: 이동할 다음 페이지 정보
  • from: 이전 페이지 정보
  • next: 다음 페이지 이동할 경우 호출됨

컴포넌트 가드에서 이동할 다음 페이지(to)로 이동할 경우 next() 호출하면 다음 경로로 이동한다.
만약 조건에 의해 인증안되는 경우 로그인 페이지로 이동할 경우 다음 형태로 가능하다.

next('/login');
next({name: 'login'});

주의할 부분은 같은 경로를 계속해서 호출하면 안된다. 예를 들어

function onBeforeEnter(to, from, next) {
    if (!isAuthorized()) return next('/login');
    //...
}

이 경우 인증안된 경우 /login 페이지로 이동하고 login 페이지에서도 인증안된 상태이기 때문에 다시 login 페이지로 이동하는 루프가 발생한다. 이 경우 해당 페이지를 예외 처리하거나 현재 페이지와 이동할 페이지가 같다면 굳이 이동할 필요가 없게 처리할 수도 있다. 만약 루프가 발생하면 vue.js에서는 navigation guard에 의해 에러가 발생한다.

function onBeforeEnter(to, from, next) {
    if (!isAuthorized()) {
        if ('/login' === router.currentRoute.path) return; // 예외페이지
        return next('/login');
    }
    //...
}

로그인 이후 원래 페이지로 이동할 경우도 있다. 로그인 페이지 이동시 파라미터로 이동 페이지 정보를 넣으면 된다.

next( {name: 'login', params: { from: to.name }} );

이렇게되면 로그인 페이지에서 해당 정보를 읽어서 페이지 이동하면 된다.

export default {
    props: {
        from: {
            type: String,
            default: 'home',
        },
    },
    methods: {
        //...
        onSuccessLogin() {
            this.$router.push({ name: this.from });
        }
    }

주의할 부분은 컴포넌트에서 props으로 값을 받으려면 라우터 설정에서 props 속성을 true로 해줘야 한다.

{
    path: '/login',
    name: 'login',
    component: () => import('@/views/Login.vue'),
    props: true,
},

참고

[1] 네베게이션 가드, 2021.10.25, https://router.vuejs.org/kr/guide/advanced/navigation-guards.html

반응형