vue + jpa project (17) - 화면이동 사전체크 및 로그아웃 처리 본문

프로그램/Vue.js

vue + jpa project (17) - 화면이동 사전체크 및 로그아웃 처리

반응형

이번 장에서는 이전 장에서 처리하지 않고 놔두었던 화면이동시 사전체크와 로그아웃 처리를 진행하겠다.

 

 Vue Router에는 네비게이션 가드를 통해 이동을 제어할 수 있는데 그 방식은 아래 3가지이다.
전역 가드, 라우트 별 가드, 컴포넌트 내부 가드 이렇게 셋이다.
이번 장에서는 라우트 별 가드를 이용하여 진행할 것이다. 

 

라우트 별 가드에서는 컴포넌트 진입 전을 제어할 수 있는 beforeEnter 가드를 지원한다. 

beforeEnter 에 선언된 함수를 호출하여 현재 상태를 확인한 이후에 다음으로 이동시킬지를 판단한다.

 

1. 화면이동시 사전체크 처리

   이미 사전체크 함수는 /util/axios.js 에 axios.requireAuth() 로 추가가 되어있다. (여기선 생략한다)

   그래서 각 업무별 라우터 js 파일에서는 /util/axios.js 를 import하여 사용한다.

   그리고 beforeEnter 가드에 해당 axios.requireAuth() 함수를 필요한 부분마다 입력한다.

... 중략
import axios from "@/util/axios"

export const BoardRouters = [
  {
    path: '/board/list',
    name: 'BoardList',
    component: BoardList,
    beforeEnter: axios.requireAuth()	// 추가된 가드
  },
  {
    path: '/board/detail',
    name: 'BoardDetail',
    component: BoardDetail,
    beforeEnter: axios.requireAuth()	// 추가된 가드
  },
  {
    path: '/board/write',
    name: 'BoardWrite',
    component: BoardWrite,
    beforeEnter: axios.requireAuth()	// 추가된 가드
  },
]

 

테스트를 위해서 axios.requireAuth 에 콘솔 로그로 한번 찍어보자. (테스트가 끝나면 삭제해도 된다)

axios.requireAuth = () => (from, to, next) => {
  const access_token = localStorage.getItem('access_token')
  const refresh_token = localStorage.getItem('refresh_token')
  if (access_token && refresh_token) {

    console.log("[[[[[사전체크]]]]]")	// 테스트를 위해서 잠깐 추가

    store.state.isLogin = true
    return next()
  } // isLogin === true면 페이지 이동
  
  store.state.isLogin = false
  next('/login') // isLogin === false면 다시 로그인 화면으로 이동
}

앞에서 내용을 설명을 하지 않아서 여기서 잠깐 설명을 한다면 access_token 과 refresh_token 두가지 모두 

존재 한다면 로그인 여부를 true 로 하고 다음 페이지로 이동시킨다.

만약 둘 중 하나라도 존재하지 않는다면 로그인 페이지로 바로 이동시킨다. from, to, next는 beforeEnter에서 

제공되는 함수이다.

 

추가한 뒤에 페이지를 리스트, 등록, 수정으로 이동시키면 아래와 같이 로그가 쌓인다. 즉 사전체크가 잘 된다는 뜻이다.

 

2. 로그아웃 처리

   로그아웃 처리는 강제 로그아웃과 토큰이 만료 되었을 경우에 처리한다. 

   우선 강제 로그아웃 처리는 아래와 같이 MainHeader.vue 를 수정한다.

<template>
  <div align="right">
    <router-link to="/login" v-if="!this.$store.state.isLogin">로그인</router-link>
    <a href="" v-if="this.$store.state.isLogin" @click="fnLogout">로그아웃</a>
  </div>
</template>

<script>
export default {
  name: 'MainHeader',
  methods: {
    fnLogout() {
      localStorage.removeItem("access_token")
      localStorage.removeItem("refresh_token")
      localStorage.removeItem("user_role")
      location.reload()
    }
  }
}
</script>

 

 

v-if 절을 이용하고 this.$store.state.isLogin 정보를 이용하여 로그인과 로그아웃을 번갈아서 보여지도록 하였다.

그리고 로그아웃 버튼을 클릭시에 fnLogout 메소드를 호출하여 localStorage에 있던 정보를 지우고

화면을 다시 리로드 한다. 리로드가 되면 위의 사전체크로 인해서 로그인 페이지로 이동한다.

로그아웃을 클릭해보자. 아래 화면대로 로그인 페이지로 이동한다. 강제로 게시판 url로도 접근해보자. 

당연히 접근이 안되고 로그인 페이지로 이동한다.

 

 

이제는 토큰이 만료가 될 경우이다. 

토큰이 만료가 되면 백엔드에서 403 오류로 무조건 리턴이 되도록 하였다.

 

그래서 axios.js의 axios.interceptors.response.use 로 수신될때 무조건 오류가 발생한다.

여기에서 강제로 처리되도록 한다.

// axios.js
import axios from "axios"
import store from "@/vuex/store.js"
import router from "@/router/router"  // 추가됨

... 중략
axios.interceptors.response.use(function(config) {
  //store.commit('LOADING_STATUS', false) --> 해당 소스는 뒤에 나오는 로딩바에 대한 것임. 추후 주석 해제

  // 새로 발급받은 액세스 토큰을 저장함
  localStorage.setItem('access_token', config.headers.access_token)
  return config
}, function (error) {

  // 아래 7줄 추가됨
  alert("로그아웃 되었습니다.");
  localStorage.removeItem("access_token")
  localStorage.removeItem("refresh_token")
  localStorage.removeItem("user_role")
  store.state.isLogin = false
  store.commit('LOADING_STATUS', false)  // 로딩바를 위해 미리 넣음
  router.push("/login")

  return Promise.reject(error);
})

테스트를 위해서 백엔드의 엑세스 토큰의 유효시간을 짧게해서 재기동을 하고 프론트에서 로그인한 뒤에 

토큰이 만료될 때까지 다른 일을 하다가 다시 화면을 리프래쉬 해보자.

로그아웃 되었다고 하고 로그인 페이지로 자동 이동된다.

 

 

이로써 사전체크와 로그아웃 처리를 완료하였다.

다음 장에서는 로딩바를 적용하여 request 요청때에 로딩바가 보여지고 

response 응답을 받으면 사라지게끔 해보겠다.

그런데 알게 모르게 이전 소스에서 이미 많이 적용이 되어 있어서 생각보다 많이 추가되지는 않는다.

반응형

프로그램/Vue.js Related Articles

MORE

Comments