✔ 로그인 후 axios headers 에 토큰 누락되는 에러 해결 : interceptors 사용
✔ 전체 폰트 Roboto 설정
✔ 스타일 변경 (모임작성버튼, 모임리스트 카드색)
❗문제발생
웹페이지 서비스에서 로그인 직후 인증이 필요한 요청을 보내게 되면, 오류가 발생하는 문제가 발생했다!
그런데.. 새로고침을 하면 된다
계속되는 빨간줄의 500에러들...
다른 팀원분이 한 페이지에서는 해당 오류가 발생하지 않아서 코드를 비교해서 고쳐봤는데,
컴포넌트에서 디스패치를 하기전에 토큰을 확인한다거나, 등은 오류에 영향을 주지 못했고
(애초에 isLogin을 통해서 페이지에서 토큰을 먼저 확인한 뒤 다른 요청들이 보내지기 때문에..)
오류가 나는 이유를 발견했다.
평소에 나는 api.js 파일을 만들어, api를 모듈화해서 사용했는데
기본적으로 사용하는 baseURL이나, headers 등의 옵션들을 미리 셋팅해뒀다.
// api.js 원래 코드
import axios from "axios";
const token = sessionStorage.getItem("token");
const instance = axios.create({
baseURL: "http://산길.com",
headers: {
Authorization: token,
"content-type": "application/json;charset=UTF-8",
accept: "application/json",
},
});
export const api = {
...
myTracking: () => instance.get("/api/mypages/tracking"),
myTitle: () => instance.get("/api/mypages/userTitle"),
...
};
// user.js 모듈
const myFeedDB = (pageNum) => {
return async function (dispatch, getState) {
api
.myFeed(pageNum)
...
};
};
같은 팀원은 아래와 같이 리덕스 미들웨어에서 바로 요청하는 방법으로 코드를 작성한 상태
// main.js 모듈
export const feedDB = (token) => {
return function (dispatch, getState) {
axios
.get("http://산길.com/api/main/feeds", {
headers: {
Authorization: sessionStorage.getItem("token"),
},
})
...
};
};
내가 작성한 페이지에서 테스트로 위와같은 방식으로 요청을 보내보니 오류가 나지 않았다.
콘솔에 찍힌 두개의 차이점을 확인해본 결과, 오류가 났을때는 토큰이 들어가 있지 않은 상황!
즉, 로그인 직후에는 Authorization 속성의 값이 null로 전달되기때문에 발생하는 오류였다.
이유를 위해 열심히 구글 검색을 해보니 처음, 로드될 때 axios 인스턴스가 생성되는데 이때 token값은 비어있는 채로 생성이 된다고한다. 이상태에서 token값이 변해도 자바스크립트단의 위 코드는 별도의 반응형이 아니기 때문에 token이 빈 상태 그대로 유지된다. 그 상태에서 api를 호출하게 되니 unauthorized 에러가 날 수 밖에 없는것!
이러한 문제를 해결하기 위해 Interceptor를 사용했다.
Interceptor는 axios가 호출되기 전(request, response 모두) 선처리 할 수 있도록 도와주는 axios 내장객체이다.
// https://github.com/axios/axios#interceptors
// 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);
}
);
기본 코드의 구조는 위와 같다. 여기서 headers - Authorization에 token값을 실어 보내면 된다.
// 추가 코드
instance.interceptors.request.use(function (config) {
const token = sessionStorage.getItem("token");
if (token) {
config.headers.Authorization = sessionStorage.getItem("token");
}
return config;
});
참고 링크