Vue에서 api와 호출할 때 axios 모듈을 사용한다.
제작중인 vue-til 애플리케이션은 리스트를 호출하거나 등록,수정,삭제를 할 때 로그인시 받았던 토큰 값이 필요하다.
인증 토큰은 Request Headers에 Authorization 속성에 값을 담아 요청하는데, 다음 코드를 보자
const instance = axios.create({
baseURL: process.env.VUE_APP_API_URL,
Headers: {
Authorization: store.state.token
}
});
axios.create를 이용하여 axios 인스턴스를 생성하는데 여기서 headers - Authorization에 store에 저장된 token을 넣고 생성한다.
이 상태로 로그인을 한 후 list를 호출할 때 통신이 가능할까?
결론부터 말하면 No다. (401 Unauthorized)
처음 vue instance가 로드될 때 axios 인스턴스가 생성되는데 이때 store에 있는 token값은 비어있는 채로 생성이 된다.
이상태에서 token값이 변해도 자바스크립트단의 위 코드는 별도의 반응형이 아니기 때문에 token이 빈상태 그대로 유지된다.
그 상태에서 list api를 호출하게 되니 Unauthorized 에러가 날 수 밖에 없는것이다.
이러한 문제를 해결하기 위해 Interceptor를 이용해본다.
Interceptor는 axios가 호출되기 전(request, response 모두) 선처리 할 수 있도록 도와주는 axios 내장객체이다.
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
});
코드의 구조는 위와 같다.
여기서 request.use의 config 인자를 console.log로 보면 다음과 같이 나온다.
여기서 우리는 headers - Authorization에 token값을 실어 보내면 된다.
// common/interceptors.js
import store from '@/store/index';
export function setInterceptors(instance) {
// Add a request interceptor
instance.interceptors.request.use(
function(config) {
console.log(config);
// Do something before request is sent
// console.log(config);
config.headers.Authorization = store.state.token;
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
},
);
// Add a response interceptor
instance.interceptors.response.use(
function(response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
},
function(error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
},
);
return instance;
}
생성한 intercoptors.js를 이용해 api/index.js 파일을 수정하면 된다.
import axios from 'axios';
import { setInterceptors } from '@/api/common/interceptors';
function createInstance() {
const instance = axios.create({
baseURL: process.env.VUE_APP_API_URL,
});
// return instance;
return setInterceptors(instance);
}
const instance = createInstance();
function registerUser(userData) {
return instance.post('signup', userData);
}
function loginUser(userData) {
return instance.post('login', userData);
}
function fetchPosts() {
return instance.get('posts');
}
export { registerUser, loginUser, fetchPosts };
다시 로그인 후 list를 조회하면 정상적으로 작동하는걸 볼 수 있다.