[Vue-DRF] Axios 인스턴스, interceptor 활용하여 토큰 관리하기

JinUk Lee·2022년 12월 27일
0

저번 포스팅에서 토큰을 갱신하는 코드까지는 작성했지만, 모든 로그인이 필요한 요청에 해당 코드를 넣는 것은 너무 비효율적이다.

그래서 우리가 사용할 방법은 axios instanceaxios interceptor 이다.

axios instanceaxios를 커스텀하여 사용하는 것이고

axios interceptoraxios에서 요청(request)이나 응답(response) 전에 가로채서 작업을 수행할 수 있게 해주는 기능이다.

https://axios-http.com/kr/docs/instance - axios instance 공식 문서

https://axios-http.com/kr/docs/interceptors - axios interceptor 공식 문서

이 두가지를 활용하여 토큰 관리를 위한 axios 코드를 작성했다.

## src/axios/index.js

import axios from 'axios'
import store from '../store'

const testaxios  = axios.create()

testaxios.interceptors.response.use(
  function (response) {
    // 200대 response를 받아 응답 데이터를 가공하는 작업
    return response
  },
  async (error) => {
    console.log('interceptors 시작')
    const {
      config,
      response: { status }
    } = error
    if (status === 403) {
      if (error.response.data.detail === '이 토큰은 모든 타입의 토큰에 대해 유효하지 않습니다') { 
      // 응답이 영어면 영어로 수정해서 사용한다.
        const originalRequest = config
        const refresh = localStorage.getItem('refresh_token')
        await store.dispatch('refreshtt', { refresh: refresh })
        const newAccessToken = localStorage.getItem('access_token')
        axios.defaults.headers.common.Authorization = `Bearer ${newAccessToken}`
        originalRequest.headers.Authorization = `Bearer ${newAccessToken}` // 새로운 토큰을 헤더에 담아줌
        // 401로 요청 실패했던 요청 새로운 accessToken으로 재요청
        return axios(originalRequest)
      }
    }
    return Promise.reject(error)
  }
)
export default testaxios

인스턴스를 생성했는데 이 인스턴스는 다음과 같이 작동한다.

1. 오류가 발생했을 때 응답을 가로채서 토큰으로 인한 오류인지를 검증
2. 원래 요청을 config에 저장하고, 로컬스토리지에 있는 refresh token을 가져옴
3. 가져온 refresh token을 기존에 작성했던 토큰 갱신 actions을 실행함.
4. 새로운 access token을 가져온 뒤 axios 헤더를 갱신해줌
5. 원래 요청의 헤더를 새로 발급받은 토큰으로 바꿔서 다시 요청을 보냄

이렇게 생성한 인스턴스를 로그인이 필요한 axios 에만 사용해준다.

<script>
import loginaxios from '../axios/index'
import axios from 'axios'
...

mounted(){
  axios.get('Article List URL') # 글 목록을 보는 것은 로그인이 필요 없다.
  ...
  loginaxios.post('Article Write URL',data) # 글을 작성하기 위해서는 로그인이 필요하다
}

이런 식으로 한 페이지 내에서도 둘 다 호출하여 로그인/비로그인 호출을 구분하여 사용할 수 있다.

profile
개발자 지망생

0개의 댓글