저번 포스팅에서 토큰을 갱신하는 코드까지는 작성했지만, 모든 로그인이 필요한 요청에 해당 코드를 넣는 것은 너무 비효율적이다.
그래서 우리가 사용할 방법은 axios instance
와 axios interceptor
이다.
axios instance
는 axios
를 커스텀하여 사용하는 것이고
axios interceptor
는 axios
에서 요청(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) # 글을 작성하기 위해서는 로그인이 필요하다
}
이런 식으로 한 페이지 내에서도 둘 다 호출하여 로그인/비로그인 호출을 구분하여 사용할 수 있다.