[Vue.js] 토큰 기반 인증(#5. 유저 로그아웃)

하수도키

·

2020. 10. 30. 00:43

728x90
반응형
SMALL

 

2020/10/31 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증 (#7. 자동 로그인)

2020/10/31 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증 catch 사용 (#6. 에러 처리)

2020/10/30 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#5. 유저 로그아웃)

2020/10/28 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#4. 유저 로그인)

2020/08/30 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#3. 사용자 등록)

2020/07/27 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#2. 인증을 위한 프로젝트 구조 살피기)

2020/07/24 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#1. 인증소개)

[Vue.js] 토큰 기반 인증(#5. 유저 로그인)

 

개요

  • 이제 로그인을 했으니 로그아웃을 만들자.
  • 생각대로 로그인 반대로 하면된다.
  • Vuex State 삭제, localStorge 삭제, Axios Header JWT Token 삭제

Logout 버튼 만들기

  • 로그아웃 버튼을 추가해보자.
  • AppNav.vue에 로그인 안했을때는 로그인 버튼이 보이고 로그인 했을때 로그아웃 버튼을 보이게 하자.
    • v-else를 사용해 분기처리함 그리고 click 이벤트시 logout 메서드 실행
    • logout 버튼 클릭시 Vuex Action logout dispatch 실행된다.
// src/components/AppNav.vue
<router-link v-if="!loggedIn" to="/login" class="button">
  Login
</router-link>
<router-link v-else type="button" class="logoutButton" @click="logout">
  LogOut
</router-link>

<script>
...
  methods: {
    logout () {
      this.$store.dispatch('logout')
    }
  }
...
</script>

Vuex: Store 추가

  • 로그인 로직(SET_USER_DATA mutation)과 반대로 작성한다.
  • logout action 추가
logout ({ commit }) {
  commit('LOGOUT')
}
  • LOGOUT mutation 추가
LOGOUT (state) {
  // 반대 로직
  state.user = null
  localStorage.removeItem('user')
  axios.defaults.headers.common['Authorization'] = null

  // 더 좋은 코드
  localStorage.removeItem('user')
  location.reload();
}
  • reload()를 사용하면 Vuex Store, Axios header가 클리어된다.

권한 라우트(페이지) 막기

  • 로그인하면 로그아웃 버튼 보이고 로그아웃 로그인 버튼 보인다.
  • dashboard에서 로그인 후 로그아웃하면 dashboard 화면에서 Loading events만 나온다.
  • 콘솔창에는 권한 없다고 나온다.(401 에러)
  • 로그아웃 상태, 즉 권한이 없을상태에서 dashboard 접속되는걸 막는법을 알아보자.

해결

  • Vue Router에 있는 navigation guard를 이용한다.
  • meta tag를 접근을 통제할 라우트에 추가한다.
  • requiresAuth를 이용해 체크한다.
//src/router.js
{
  path: '/dashboard',
  name: 'dashboard',
  component: Dashboard,
  meta: { requiresAuth: true }
},
  • beforeEach : 글로벌 Route 모든 라우트에 접근할때마다 발생 3가지 인자를 받는다.
    • to: 이동 할 라우트
    • from: 현재 라우트
    • next : function called to resolve the hook(이 훅을 해결하고 난 뒤 불러야 되는 함수 - 필수)
// /src/router.js
router.beforeEach((to, from, next) => {
    // 여기서 무엇을 해야 할까?
})
  • 이 가드안에서 2가지 일을 해야 한다.
    • 유져가 로그인 한 상태인가?
    • 이동되어지는 라우트에 requireAuth가 있는가?
  • 1번을 해결하기 위해 localStorge를 체크한다.
router.beforeEach((to, from, next) => {
  // 1번 해결 로컬스토리지 체크
  const loggedIn = localStorage.getItem('user')

  console.log(to)

  // 2번 해결 requiresAuth 체크
  if (to.matched.some(record => record.meta.requiresAuth)) {
      // 로그인 상태가 아니면 '/' 여기로 보내버린다.
      if (!loggedIn) {
          next('/')
          return
      }
      next()
  }
  // requiresAuth가 false일때 즉, 권한이 필요 없는 페이지 일때
  next()
)
  • 라우트가 이동될때 to 라우트 레코드 matched 속성에서 recoard.meta.requiresAuth가 만족(true)이면 로그인 권한을 체크한다.
  • 체크 후 로그인이 되어있지 않으면 (/)으로 가고 로그인이되어있으면 정상적으로 라우팅된다.
  • console.log(to)
{name: "dashboard", meta: {…}, path: "/dashboard", hash: "", query: {…}, …}
fullPath: "/dashboard"
hash: ""
matched: Array(1)
    beforeEnter: undefined
    components: {default: {…}}
    instances: {}
    matchAs: undefined
    meta: {requiredAuth: true}
    name: "dashboard"
    parent: undefined
    path: "/dashboard"
    props: {}
    redirect: undefined
    regex: /^\/dashboard(?:\/(?=$))?$/i
    __proto__: Object
    length: 1
    __proto__: Array(0)
meta: {requireAuth: true}
name: "dashboard"
params: {}
path: "/dashboard"
query: {}
__proto__: Object
  • 코드를 더 축약해보자
router.beforeEach((to, from, next) => {
  const loggedIn = localStorage.getItem('user')
  if (to.matched.some(record => record.meta.requireAuth) && !loggedIn) {
    next('/')
  }
  next()
})

대시보드 링크 숨기기

  • 로그인시에 보이는 Dashboard를 로그아웃 될때는 보이지 않게 하자
  • v-if를 사용해 로그인시에만 링크가 보이게 한다.
// src/components/AppNav.vue
<router-link v-if="loggedIn" to="/dashboard">
  Dashboard
</router-link>

정리

  • 로그인과 반대의 로직인 로그아웃이다.
  • 로그아웃을 reload()를 통해 효율적으로 간단히 하는 법을 배웠다.
  • 로그인 유무에 따른 분기처리 작업
  • 다음 포스팅은 에러 다루는걸로!!
728x90
반응형
LIST