현재 실무 vue 서비스에서
클라이언트에서 로컬스토리지의 액세스 토큰 유무로 로그인/비로그인을 판단한다.
axios를 사용하여 HTTP 요청을 보내고 응답을 처리하는 wrapper 함수로 동작 중 이다. 여기서는 axios의 요청 및 응답 인터셉터를 사용하여 특정 상황에 대한 처리를 구현하고 있다.
🍒 실무에서 axios 이용한 로그인, 로그아웃 기능 #1
🍒 trouble issue -> trouble shooting #2
🔎 #1. 현재 접속하고 일정시간 지나면 자동으로 로그아웃 되는 부분의 기능이 어떻게 동작중인가?
토큰 자체가 갖고 있는 정보로 브라우저의 시간과 비교해서 로그아웃 당함
로그아웃 로직은 API 호출 시 응답의 상태코드 보고 처리 (서버에서 토큰의 유효기간을 보고 이 토큰은 유효하다 or 유효하지 않다 평가해서 내려줌)
ex) 실무 api
토큰 만료기간 도달 401 , 권한 없음 403 인경우
→ 스토리지 토큰 제거
JMT 토큰 :
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' 카테고리의 다른 글
jsPDF 이미지파일 pdf에 추가, 한글 깨짐 문제 (base64) (0) | 2024.04.27 |
---|---|
"모던 프론트엔드" 에 대해 (0) | 2024.03.30 |
[CSS] z-index 의 동작방식 (1) | 2024.03.04 |
[typescript] any VS unknown (0) | 2024.02.21 |
CORS (0) | 2023.09.06 |