똑같은 삽질은 2번 하지 말자

Vue.js 끝내기 No.9(인증 토큰,HTTP헤더에 토큰 실는방법,Axios 인터셉터) 본문

Vue

Vue.js 끝내기 No.9(인증 토큰,HTTP헤더에 토큰 실는방법,Axios 인터셉터)

곽빵 2020. 5. 21. 00:59

/posts 신청시 Token이 필요하게 API가 설정되어있다.

서버에 로그인 했을때, 토큰값이 반환되는게 보일 것이다.

저 토큰 방식은 JSON Web 토큰 형식

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

그러면 어떻게 저 토큰값을 서버에 넘기면서 문제없이 API를 이용할 수 있을까?

 

HTTP 헤더에 실어서 보내는 방법이 있다.

 

import axios from 'axios';

const instance = axios.create({
  baseURL: process.env.VUE_APP_API_URL,
  headers: {
    Authorization: 'test1234', // header의 속성
  },
});

function registerUser(userData) {
  return instance.post('signup', userData);
}

function loginUser(userData) {
  return instance.post('login', userData);
}

export { registerUser, loginUser };

이렇게 create의 instance에다가 headers의 정보를 실어서 보낼 수 있다,(axios.create는 저번에 배운 친구)

(process.env는 환경설정 파일로 만들어둔 친구)

 

test1234가 담겨져 있다는게 확인가능하다.

 

자 그럼, token을 빼와서 store의 state에 저장하고 필요할때, 갖다가 써보자.

store/index.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    username: '',
    token: '',
  },
  getters: {
    isLogin(state) {
      return state.username !== '';
    },
  },
  mutations: {
    setUsername(state, username) {
      state.username = username;
    },
    setToken(state, token) {
      state.token = token;
    },
    clearUsername(state) {
      state.username = '';
    },
  },
});

LoginForm.vue

methods: {
    async submitForm() {
      try {
        // 비즈니스 로직
        const userData = {
          username: this.username,
          password: this.password,
        };
        const { data } = await loginUser(userData);
        this.$store.commit('setUsername', data.user.username);
        this.$store.commit('setToken', data.token); // 토큰 셋팅
        this.$router.push('/main');
      } catch (error) {
        // 에러 핸들링할 코드
        console.log(error.response.data);
        this.logMessage = error.response.data;
      } finally {
        this.initForm();
      }
    },
    initForm() {
      this.username = '';
      this.password = '';
    },
  },

api/index.js

import axios from 'axios';
import store from '../store/index.js';

const instance = axios.create({
  baseURL: process.env.VUE_APP_API_URL,
  headers: {
    Authorization: store.state.token, // store에서 불러오기
  },
});

function registerUser(userData) {
  return instance.post('signup', userData);
}

function loginUser(userData) {
  return instance.post('login', userData);
}

export { registerUser, loginUser };

but, api/index.js가 셋팅되는 시점은 이미 훨씬 전이기때문에 네트워크패널을 살펴보면 이미 빈값으로 들어가 있는걸 

확인할 수 있다.

그럼 어떻게 해야할까?

Axios Interceptors

 

https://github.com/axios/axios#interceptors

 

axios/axios

Promise based HTTP client for the browser and node.js - axios/axios

github.com

import store from '@/store/index.js';

export function setInterceptors(instance) {
  // Add a request interceptor
  instance.interceptors.request.use( // login API 요청후 
    function(config) {
      // Do something before request is sent
      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;
}
Comments