HTTP 헤더 토큰 설정 & axios 인터셉터

김승우·2021년 1월 18일
2

Vue TIL

😎 캡틴판교님의 vue 강의를 듣고 정리한 노트입니다.

강의 주소 : https://www.inflearn.com/course/vue-js-%EB%81%9D%EB%82%B4%EA%B8%B0-%EC%BA%A1%ED%8B%B4%ED%8C%90%EA%B5%90

  • git checkout -f(force)
    : -f 옵션을 사용하면 기존의 코드를 모두 덮어쓰게된다.

  • HTTP 401 코드 : 권한이 없음을 나타내는 코드(unAuthroized)

  • 토큰 : 사용자가 인증되었을 경우 발급하는 데이터, 이 값을 통해 인증 여부를 판단한다.

  • jwt(json web token) : 대표적으로 사용하는 토큰
    : https://jwt.io/

  • ✨✨ HTTP 헤더에 토큰 값을 실는 방법
    : axios config 객체 headers 안에 있는 Authrozation 속성에 토큰 값을 할당해 주면 된다.

const instance = axios.create({
	baseURL: '',
	headers: {
		Authrozation: 'testToken',
	}
})

  • Vuex Store를 이용한 토큰 관리
    : state에 token 프로퍼티 생성, state를 변경시킬 mutations 정의

    👀 왜 state에 토큰 값을 저장할까? 서버에서 인증이 필요한 api를 통해 데이터를 요청하기 위해서 토큰 값을 HTTP 헤더에 실어줘야한다. 이때, api/index.js 파일을 통해서 api 관련 로직을 분리했으므로, api/index.js 파일에서
    해당 토큰에 접근할 수 있는 방법이 필요하다. 이때 생각나는 방법이 토큰을 전역 변수로 설정해두고, 로그인하면 이 전역변수에 값을 할당하는 방법이다. 이처럼 스토어가 전역변수 역할을하기 때문에 스토어에 토큰 값을 할당하고 쉽게 다른 파일, 컴포넌트에서도
    토큰 값에 접근할 수 있다.

//store/index.js
state: {
	token: '',
},
mutations: {
	setToken(state, token) {
		state.token = token;
	},
}
  • Vue 파일을 제외한 다른 파일에서 Vuex Store 객체 접근하기
import store from '@/store/index';

//store의 속성에 접근 가능
const token = store.state.token;

뷰 컴포넌트에서는 $store를 통해서 스토어 인스턴스에 접근할 수 있지만 그 외 다른 파일에서는 import를 통해서 스토어 인스턴스를 가져와 해당 객체를 사용할 수 있다.

  • ✨ 최초 인스턴스 생성 시, 토큰 값을 설정할 때 발생한 문제점
//api/index.js
import store from '@/store/index';

const instance = axios.create({
  baseURL: process.env.VUE_APP_API_URL,
  headers: {
    Authrozation: store.state.token,
  },
});

최초 프로젝트가 실행될 때, 스토어의 token 값이 빈 문자열이므로 api/index.js 파일이 최초 실행될 때(자바스크립트 레벨에서 파일이 생성될 때) Authrozation 값이 빈 문자열로 설정된다.
따라서, 스토어의 토큰 값을 변경해도 Axios 인스턴스의 Authrozation 값이 변경되지 않는 문제가 발생했다. => Axios 인터셉터를 이용해 헤더에 토큰 값을 실어 보내면서 해결할 수 있다.

✨✨✨ Axios 인터셉터

  • docs : https://github.com/axios/axios#interceptors
  • 정의 : 인터셉터는 요청(request) 직전, 응답을 받고(response) then, catch로 처리하기 직전에 동작을 제어할 수 있다.(말 그대로 가로채기!)
  • 기본 소스 예시
// 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);
  });

axios 부분을 axios.create()로 생성한 인스턴스로 대체하는 것이 좋다.

  • ✨✨ Axios 인터셉터 설정 및 로직 분리
    1) 폴더 구조

    2) interceptors.js 소스
function setInterceptors(instance) {
  instance.interceptors.request.use(
    function(config) {
      return config;
    },
    function(error) {
      return Promise.reject(error);
    },
  );

  // Add a response interceptor
  instance.interceptors.response.use(
    function(response) {
      return response;
    },
    function(error) {
      return Promise.reject(error);
    },
  );

  return instance;
}

export default setInterceptors;

setInterceptors 함수는 인자로 axios instance를 전달받고, 인터셉터 설정 로직을 실행한 후에 인스턴스를 다시 리턴해주는 함수이다.

3) api/index.js 파일 소스

function createInstance() {
  const instance = axios.create({
    baseURL: process.env.VUE_APP_API_URL,
  });

  return setInterceptors(instance);
}

const instance = createInstance();

인스턴스를 생성하고, 인터셉터 설정 로직까지 완료된 후에 새로운 인스턴스를 리턴하는 로직을 하나의 함수로 만들었다. createInstance()의 리턴 값(인스턴스)을 이용해서 api를 요청한다.

4) ✨✨ 인터셉터를 이용해서 요청 전에 토큰 값 실기

import store from '@/store/index';

instance.interceptors.request.use(
	function(config) {
	  // 1. 요청 보내기 전에 실행
	  // store의 토큰 값 설정
	  config.headers.Authrozation = store.state.token;
	  return config;
	},
	function(error) {
	  // Do something with request error
	  return Promise.reject(error);
	},
);

인터셉터 request에 설정된 1번 라인이 axios를 이용해서 api를 요청할 떄마다 실행되는 것을 볼 수 있다.
config.headers.Authrozation 값이 스토어의 token 값을 전달한다.
=> 인터셉터를 이용해서 매 요청 때마다 스토어에 있는 토큰 값을 가져와서 HTTP 헤더에 전달할 수 있다.


profile
사람들에게 좋은 경험을 선사하고 싶은 주니어 프론트엔드 개발자

0개의 댓글