본문 바로가기

frond-end

로그아웃 시 다른 에러 상태 코드 도 같이 보여주는 문제 (axios + vue3)

현재 실무 vue 서비스에서

클라이언트에서 로컬스토리지의 액세스 토큰 유무로 로그인/비로그인을 판단한다.

axios를 사용하여 HTTP 요청을 보내고 응답을 처리하는 wrapper 함수로 동작 중 이다. 여기서는 axios의 요청 및 응답 인터셉터를 사용하여 특정 상황에 대한 처리를 구현하고 있다.

 

 

 

 

🍒 실무에서 axios 이용한 로그인, 로그아웃 기능 #1
🍒 trouble issue -> trouble shooting #2

 

 

 

 

 


 

 

 

 

 

 


🔎 #1.  현재 접속하고 일정시간 지나면 자동으로 로그아웃 되는 부분의 기능이 어떻게 동작중인가?


 

토큰 자체가 갖고 있는 정보로 브라우저의 시간과 비교해서 로그아웃 당함

로그아웃 로직은 API 호출 시 응답의 상태코드 보고 처리 (서버에서 토큰의 유효기간을 보고 이 토큰은 유효하다 or 유효하지 않다 평가해서 내려줌)

 

ex) 실무 api 
토큰 만료기간 도달 401 , 권한 없음 403 인경우
→ 스토리지 토큰 제거 

 

 

 

 

 

 

JMT 토큰 : 

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

JWT토큰을  https://jwt.io/ 디코더하면 확인 가능하다.

 

 

 

 

 

 

 

 

 

 

⛓️ axios.ts 코드 

 axios.interceptors.request.use((request: any) => {
    const router = app.config.globalProperties.$router
    if (window.localStorage.getItem('token')) {
      return request
    } else if (
      !router.currentRoute.value.path ||
      router.currentRoute.value.path === '/' ||
      router.currentRoute.value.path === '/login'
    ) {
      return request
    } else {
      router.push('/login')
    }

1️⃣ axios 요청 인터셉터:

  • 요청이 발생하기 전에 localStorage에서 토큰을 확인하여 인증된 사용자인지 확인.
  • 만약 토큰이 없고, 현재 경로가 '/' 또는 '/login'이 아니면 '/login' 페이지로 리다이렉트.
  • 요청에 대한 처리가 끝나면 요청을 반환.

 

 

axios.interceptors.response.use(
    (response: any) => {
      switch (response.status) {
        case 202:
          ...
          const { data } = response
          ...
          break
      }
      return response
    },
    async (error: any) => {
      // response가 없을 때
      error.response = error.response ? error.response : {}
      error.response.status = error.response.status ? error.response.status : 999

      const errorStatus = error.response.status

      switch (errorStatus) {
        case 401:
          Notify.create({
            type: 'negative',
            message: '인증에 실패했습니다.',
          })
          await logout(app.config.globalProperties.$router)
          break
        case 403:
         ...
        case 500:
         ...
      }

      // 400 에러는 store 에서 처리
      return Promise.reject(error)
    }
  )
  • 응답이 202 상태 코드인 경우, 메시지를 설정.
  • 응답이 에러인 경우에 대한 처리.
    • 401 상태 코드인 경우 세션 만료 토스트 메시지를 표시하고 로그아웃 후 로그인 페이지로 이동합니다.
    • ~ 상태 코드인 경우에는 예상하지 못한 오류 메시지를 표시합니다.
    • 기타 알 수 없는 에러인 경우에는 알 수 없는 에러 메시지를 표시합니다.
  • 마지막으로 Promise.reject(error)를 반환하여 오류를 처리합니다.

 

 

3️⃣ 추가적으로

axios 인스턴스 및 컴포넌트 프로퍼티로 등록:

  • axios를 모듈로 내보내고, Vue 컴포넌트에서 $axios 프로퍼티를 사용할 수 있도록 선언 해줘서 사용 중.

 

 

 

 

 

 


 

 

 

 

 

 

 


🔥 #2.  Trouble Issue : 로그아웃 시 다른 에러 상태 코드 도 같이 보여주는 문제


1. 문제정의

  • 문제가 되는 동작 → 
  • 토큰기한이 초과되서 로그아웃을 당하는데, 403에 해당하는 이슈(logout API 호출시 응답의 상태코드)만 뜨는 게 아니라, 500에러가 같이 표시.

 

 

2. 사실 수집

  • 유저는 자동 로그 아웃시, 다른 에러 메시지도 보여 페이지 자체가 문제가 생겼다고 인지

 

 

 

3. 조치 방안 아이디어

  • 토큰 유효시간으로 타임아웃 걸어서 확인 or 500 에러에서 토큰 checking

 

 

 

 

 

 

 

 

 

 

💡 Trouble Shooting


세션 만료 토스트 메시지 및 로그아웃 처리

  • sessionExpiredToast 함수는 lodash의 debounce를 사용하여 세션 만료 토스트 메시지를 지연하여 여러 번 호출되지 않도록 한다.
  • debounce : 특정 함수가 여러번 반복 실행될 경우, 정해진 지연시간동안 반복된 호출을 마지막에 딱 1번만 호출하도록 제어해준다.

 

 

import { debounce } from 'lodash'


const sessionExpiredToast = debounce((message: string) => {
  Notify.create({
    type: 'positive',
    icon: '',
    message,
  })
}, 500)


switch (errorStatus) {
        case 401:
          sessionExpiredToast('세션이 만료되어 로그아웃되었습니다.')
          await logout(app.config.globalProperties.$router)
          break
        case 403:
          sessionExpiredToast('세션이 만료되어 로그아웃되었습니다.')
          await logout(app.config.globalProperties.$router)
          break
        case 500:
          Notify.create({
            type: 'negative',
            message: '예상하지 못한 오류가 발생했습니다 .',
          })
          ....

 

✔︎ 에러메시지에 실행되는 함수에 debounce 를 걸어 가장 마지막에 실행되는 토스트만 실행되도록 구현

 

 

 

 

 

자동 로그아웃 시 api 상태코드에 대한 처리만 되게 하였다.

 

 

728x90
반응형

'frond-end' 카테고리의 다른 글

"모던 프론트엔드" 에 대해  (0) 2024.03.30
Frontend-Tech-handbook (.~ daily update )  (0) 2024.03.08
[CSS] z-index 의 동작방식  (1) 2024.03.04
[typescript] any VS unknown  (0) 2024.02.21
CORS  (0) 2023.09.06