Axios Interceptor

devjune·2021년 7월 13일
1

Vue.js

목록 보기
33/36
post-custom-banner

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 내장객체이다.

Axios-Interceptor github 링크

// 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를 조회하면 정상적으로 작동하는걸 볼 수 있다.

profile
개발자준
post-custom-banner

0개의 댓글