[Booksle] axios request header 값 설정

halloyun·2024년 3월 11일
1
post-thumbnail

해당 글은 스프린트 2 도서구매사이트 개발을 기반으로 하고 있습니다.

원래 프로젝트의 instance 코드다. 일반적인 instance생성시 headers에 필요한 정보들을 기입하는 방식인데 "content-type": "application/json",는 잘 넘어오지만 Authorization의 token 값이 넘어오지 않는 오류가 발생했다.

  1. 로그인 후, token이 생성되었지만 headers값에 token이 들어오지않는다.
  2. 새로고침 후, headers의 Authorization에 token 값이 들어와있는걸 알 수 있었다.


해당 스크린샷은 token값이 누락된 상태다.

초기 코드

import axios, { AxiosRequestConfig } from "axios";
import { getToken, removeToken } from "../store/authStore";

const BASE_URL = "http://localhost:9999";
const DEFAULT_TIMEOUT = 30000;

export const createClient = (config?: AxiosRequestConfig) => {
    const axiosInstance = axios.create({
        baseURL: BASE_URL,
        timeout: DEFAULT_TIMEOUT,
        headers: {
            "content-type": "application/json",
            Authorization: getToken() ? getToken() : "",
        },
        withCredentials: true,
        ...config,
    });

    axiosInstance.interceptors.response.use(
        (response) => {
            return response;
        },
        (error) => {
            if (error.response.status == 401) {
                removeToken();
                window.location.href = "/login";
                return;
            }
            return Promise.reject(error);
        }
    );

    return axiosInstance;
};

export const httpClient = createClient();

해당 문제는 꽤 간단했는데 오류 발생 원인은 다음과 같다.

  1. 최초 api통신을 할때 인스턴스를 생성한다. 이때는 token이 없다.
  2. 그렇기에 Authorization에는 token이 없이 생성된다.
  3. 로그인을 한 후에 token이 생성되어도 이미 생성된 인스턴스는 변경되지 않는다.

새로고침을 하면 token값이 정상적으로 header에 들어가게 되는데 그 이유는 챗지피티를 통해서 확인할 수 있었다.

자바스크립트 코드가 실행되는 환경에서는 일반적으로 페이지 새로고침이 발생하면 해당 페이지의 자바스크립트 코드가 처음부터 다시 실행됩니다. 이것은 브라우저의 동작 방식 중 하나입니다. 새로고침이 발생하면 현재 페이지의 모든 자바스크립트 코드가 다시 로드되어 실행되는데, 이는 페이지의 상태를 초기화하고 자바스크립트 애플리케이션을 다시 시작하는 것으로 이해할 수 있습니다.
axios 인스턴스는 자바스크립트 코드가 실행되는 중에 생성될 수 있습니다. 예를 들어, 애플리케이션이 로드될 때 초기화 코드에서 axios 인스턴스를 생성할 수 있습니다. 이러한 경우에는 페이지 새로고침이 발생하면 초기화 코드가 다시 실행되어 axios 인스턴스도 다시 생성됩니다.
따라서 새로고침이 발생하면 axios 인스턴스가 다시 생성되어서 이전의 설정된 값들이 초기화되고, 새로운 설정값이 적용됩니다. 이것이 Authorization 헤더에 새로운 토큰이 설정되는 이유입니다. 페이지 새로고침은 애플리케이션을 다시 시작하는 것과 유사하게 동작하며, 이 과정에서 axios 인스턴스가 초기화되고 새로운 설정이 적용됩니다.

그렇기때문에 더욱 확실하게 token값을 요청에 보내고 싶다면 인터셉터 함수를 통해서 axios 요청이 이루어지기전에 token 값을 인스턴스 설정에 넣는 방법이 있다.

그래서 수정된 코드는 다음과 같다.

수정된 코드

import axios, { AxiosRequestConfig } from "axios";
import { getToken, removeToken } from "../store/authStore";

const BASE_URL = "http://localhost:9999";
const DEFAULT_TIMEOUT = 30000;

export const createClient = (config?: AxiosRequestConfig) => {
    const axiosInstance = axios.create({
        baseURL: BASE_URL,
        timeout: DEFAULT_TIMEOUT,
        headers: {
            "content-type": "application/json",
            Authorization: getToken() ? getToken() : "",
        },
        withCredentials: true,
        ...config,
    });

    //요청시 헤더에 토큰 값 넣기
    axiosInstance.interceptors.request.use(function (config) {
        config.headers.Authorization = getToken() ? getToken() : "";
        return config;
    });

    axiosInstance.interceptors.response.use(
        (response) => {
            return response;
        },
        (error) => {
            if (error.response.status == 401) {
                removeToken();
                window.location.href = "/login";
                return;
            }
            return Promise.reject(error);
        }
    );

    return axiosInstance;
};

export const httpClient = createClient();

이렇게하면 요청 시 token 값을 가져오기 때문에 token이 누락되는 상황이 발생하지 않는다.


참고

profile
안뇽! 자기소개는 밝게

0개의 댓글