코딩하는 둥둥

라우터 네비게이션 가드 본문

Frontend/Vue.js

라우터 네비게이션 가드

둥둥 2022. 9. 27. 15:55
728x90

라우터 네비게이션 가드

References.

(중급) Vue.js 라우터 네비게이션 가드 알아보기

 

(중급) Vue.js 라우터 네비게이션 가드 알아보기

뷰 라우터를 사용할 때 알아두면 좋은 네비게이션 가드 설명. 특정 페이지로 넘어가기 전에 검증 로직 추가하기

joshua1988.github.io

네비게이션 가드 (navigation guard)

뷰 라우터로 특정 URL에 접근할 때 해당 URL의 접근을 막는 방법을 말한다.

예를 들어, 사용자의 인증정보가 없으면 특정 페이지에 접근하지 못하게 할때 사용된다.

네비게이션 가드의 종류
  • 전역 가드 : 애플리케이션 전역에서 동작
  • 라우터 가드 : 특정 URL에서만 동작
  • 컴포넌트 가드 : 라우터 컴포넌트 안에 정의

전역 가드 : beforeEach()

애플리케이션 전역에서 동작하며, 라우터 인스턴스를 참조하는 객체로 설정할 수 있다.

  1. 전역 가드 설정을 위해 먼저 라우터 인스턴스 생성
var router = new VueRouter();
  1. router 변수에 .beforeEach() API 호출

*이때 해당 코드의 위치는 라우터 인스턴스와 뷰 인스턴스 사이!

router.beforeEach(function (to, from, next) {
  // to : 이동할 url 정보가 담긴 라우터 객체
  // from : 현재 url 정보가 담긴 라우터 객체
  // next : to에서 지정한 url로 이동하기 위해 꼭 호출해야 하는 함수
});

· · · ·

<body>
    <div id="app">
        <div>
            <router-link to="login">Login</router-link>
            <router-link to="main">Main</router-link>
        </div>
        <router-view></router-view>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 1. vue.js 스크립트 * 순서중요! -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script> <!-- 2. vue router : 버전 표시하지 않으면 vue3로 사용되므로 주의 -->

    <script>
        var LoginComponent = {
            template: '<div>login</div>'
        }
        var MainComponent = {
            template: '<div>main</div>'
        }

        var router = new VueRouter({
            routes: [
                {
                    path: '/login',
                    component: LoginComponent
                },
                {
                    path: '/main',
                    component: MainComponent
                }
            ]
        });

        router.beforeEach(function (to, from, next){
            // 전역 가드 설정
            console.log('라우터 네비게이션 : 전역 가드 설정');
        });

        new Vue({
            el: '#app',
            router: router 
        });

    </script>
</body>

Untitled

전역 가드 설정 후 /login이나 /home으로 이동하더라도 라우팅이 되지 않고 콘솔에 로그만 출력된다.

Untitled

이때 원하는 url로 이동하고싶다면 console.log()대신 next()를 쓰면 된다.

✔ 전역 가드로 페이지 인증 정보 확인

  • Login 라우터 컴포넌트에 autoRequired: true라는 meta정보를 추가하여 사용자 인증 여부를 체크한다.
  • 이동할 페이지에 인증 정보가 필요하면 경고 창을 띄우고 페이지 전환은 하지 않는다.
router.beforeEach(function (to, from, next){
            // 이동할 페이지에 해당하는 라우팅 객체
            if (to.matched.some(function(routeInfo) { 
                // 이동할 페이지 url.mathced.some 
              // => 이동할 페이지와 (routeInfo함수의 모든 요소를 검사해 조건을 만족시카면 true)비교해 일치하면 routeInfo.meta.authRequired의 불린값 return
                return routeInfo.meta.authRequired;
            })) {
                // else if : 이동할 페이지에 인증 정보가 필요하면 경고 창을 띄우고 페이지 전환은 하지 않음
                alert('Login Please!');
            } else { // else : 이동할 페이지에 인증정보가 없으면 next()
                console.log("routing success : '" + to.path + "'");
                next(); // 페이지 전환
            };

        });
  • 만약 이동하려는 페이지에 인증정보가 true일 경우 : routeInfo.meta.authRequired 리턴
  • 만약 이동하려는 페이지에 인증정보가 필요할 경우 (false) : 경고창을 띄우고 페이지 전환은 하지 않음.
  • 이동하려는 페이지에 인증정보가 필요없을 경우 : next(). 페이지 전환
  • to.matched.some(function(routeInfo))matched : 라우트에 매칭된 값이 저장됨. URL에 대해서 match가 된 route들을 저장. 이것이 두개 이상이 될 수 도 있다. https://router.vuejs.org/api/interfaces/routelocationnormalizedloaded.html#matched..?routeInfo :⇒ matched 배열 안에 meta속성이 있으면, authRequired의 속성의 값을 리턴하라. 그리고 이후 검증할 요소들이 있더라도 진행을 중지한다.(forEach문과 다른 부분)
  • → 이동할 페이지의 불린값과 (routeInfo함수의 모든 요소를 검사해 조건을 만족시키면 true)를 비교
  • .some : 자바스크립트 내장 API. 지정된 배열의 모든 요소를 검사하여 조건을 만족시키면 true값을 반환하고 아니면 false 값을 반환한다.
  • to : 이동할 페이지의 url에 해당하는 라우팅 객체
  • 전체 코드
  • <body> <div id="app"> <div> <router-link to="login">Login</router-link> <router-link to="main">Main</router-link> </div> <router-view></router-view> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 1. vue.js 스크립트 * 순서중요! --> <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script> <!-- 2. vue router : 버전 표시하지 않으면 vue3로 사용되므로 주의 --> <script> var LoginComponent = { template: '<div>login</div>' } var MainComponent = { template: '<div>main</div>' } var router = new VueRouter({ routes: [ { path: '/login', component: LoginComponent, meta: {authRequired: true} // meta 정보에 authRequired라는 Boolean 값 → 추가사용자 인증 여부 : true일 경우에만 접속 가능 }, { path: '/main', component: MainComponent } ] }); // router navigation 추가해보기! // router.beforeEach(function (to, from, next){ // // to : 이동할 url // // from : 현재 url // // next : to에서 지정한 url로 이동하기 위해 꼭 호출해야 하는 함수. 해당 함수가 호출되기 전까지는 화면이 전환되지 않음. // }); router.beforeEach(function (to, from, next){ // 이동할 페이지에 해당하는 라우팅 객체 if (to.matched.some(function(routeInfo) { // 이동할 페이지 url.mathced.some => 이동할 페이지와 (routeInfo함수의 모든 요소를 검사해 조건을 만족시카면 true)비교해 일치하면 routeInfo.meta.authRequired의 불린값 return return routeInfo.meta.authRequired; })) { // else if : 이동할 페이지에 인증 정보가 필요하면 경고 창을 띄우고 페이지 전환은 하지 않음 alert('Login Please!'); } else { // else : 이동할 페이지에 인증정보가 없으면 next() console.log("routing success : '" + to.path + "'"); next(); // 페이지 전환 }; }); new Vue({ el: '#app', router: router }); </script> </body>

UntitledUntitled

localhost/에 접근할때는 해당페이지에 접근하기위해 인증정보가 필요없으므로 next()로 페이지를 전환해 콘솔에 “routing success: ‘/’”로 찍한것을 확인할수 있다.

마찬가지로 main페이지 또한 접근하기위해 인증정보가 필요없으므로 next()로 페이지를 전환해 “routing success : ‘/main’”이 찍힌것을 확인할수 있다.

하지만 login페이지는 인증정보가 필요한 페이지이므로 인증정보 없이 접근 시도(authRequired=’fasle’)시 “Login Please!”라는 alert창이 뜨고 페이지가 전환되지 않는다.

→ 따라서 인증값이 필요한 페이지는 라우팅을 막는것을 확인할 수 있었다.

라우터 가드 : beforeEnter

전체 라우팅이 아닌 특정 라우팅에 대해서 가드를 설정한다.

var router = new VueRouter({
  routes: [
    {
      path: '/login',
      component: Login,
      beforeEnter: function(to, from, next) {
        // 인증 값 검증 로직 추가
      }
    }
  ]
})

✔ 라우터 가드로 페이지 인증 정보 확인

var router = new VueRouter({
            routes: [
                {
                    path: '/login',
                    component: LoginComponent,
                },
                {
                    path: '/main',
                    component: MainComponent,
                    meta: {authRequired: false},
                    // 라우터 가드 : main
                    beforeEnter: function(to, from, next){
                        // 인증 값 검증 로직 추가 
                        if (to.matched.some(function(routeInfo) { 
                            return routeInfo.meta.authRequired;
                        })) {
                            alert('beforeEnter : Login Please!');
                        } else {
                            console.log("beforeEnter : routing success : '" + to.path + "'");
                            next(); // 페이지 전환
                        };

                    }
                },
                {
                    path: '/admin',
                    component : AdminComponent,
                }
            ]
        });

라우터 가드를 설정하지 않은 localhost/, /login, /admin으로 이동시 콘솔에 아무것도 찍히지 않고, 라우터 가드를 설정한 /main으로 이동시 인증 여부를 판단한다.

컴포넌트 가드 : beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave

라우터로 지정된 특정 컴포넌트에 가드를 설정하는 방법이다.

컴포넌트 단위로, 스크립트에 작성한다는것이 특징이다.

var AdminComponent = {
            template : '<div>admin</div>',
            // 컴포넌트 가드
            beforeRouteEnter(to, from, next){
                // admin 컴포넌트가 화면에 표시되기 전에 수행될 로직 → localhost/에 진입했을때 출력.
                // admin 캄포넌트는 아직 생성되지 않은 시점
                console.log("beforeRouteEnter : admin 컴포넌트가 화면에 표시되기 전에 수행될 로직");
                next(); // next()추가시 이동 가능.
            }, 
            beforeRouteUpdate(to, from, next){
                // 화면에 표시된 컴포넌트가 변경될때 수행될 로직 → admin에서 다른 컴포넌트로 이동시 발생
                // 'this'로 admin 컴포넌트를 접근할 수 있음
                console.log(" beforeRouteUpdate: 화면에 표시된 컴포넌트가 변경될때 수행될 로직");
            }, 
            beforeRouteLeave(to, from, next){
                // admin 컴포넌트를 화면에 표시한 url 값이 변경되기 직전의 로직 → 같은 라우터 내에서 이동하는 거라 안되나?
                // 'this'로 admin 컴포넌트를 접근할 수 있음
                console.log("beforeRouteLeave : 화면에 표시된 컴포넌트가 변경될때 수행될 로직");
            }
        }
  • beforeRouteEnter : 컴포넌트가 화면에 표시되기 전(컴포넌트가 아직 생성되지 않은 시점)에 수행될 로직
  • beforeRouteUpdate : 화면에 표시된 컴포넌트가 변경될 때 수행될 로직
  • beforeRouteLeave : 다른 라우터로 이동할 때 실행

References

[vue-router] 라우터 메타 필드

네비게이션 가드와 route 인증

Navigation Guard | Cracking Vue.js

Vue-Router - 라우터 네비게이션 가드

728x90