axios 의 interceptor response를 사용해 액세스 토큰이 만료되면 리프레쉬 하는 로직을 쉽게 구현 할 수 있다.
전체 코드
import axios, { Axios, AxiosError } from "axios";
class API {
api: Axios;
constructor() {
this.api = axios.create();
this.setBaseURL();
this.setAuthorization();
this.setInterceptor();
}
setBaseURL() {
this.api.defaults.baseURL = process.env.NEXT_PUBLIC_SERVER_URL;
}
setAuthorization() {
if (typeof window !== "undefined") {
const accessToken = window.localStorage.getItem("accessToken");
const authorization = accessToken ? `Bearer ${accessToken}` : "";
this.api.defaults.headers.common["Authorization"] = authorization;
}
}
setInterceptor() {
this.api.interceptors.response.use(
(res) => res,
async (error: AxiosError) => {
const { config, response } = error;
if (
response?.status === 401 &&
window.localStorage.getItem("accessToken")
) {
const accessToken = await this.refresh();
if (accessToken) {
return axios({
...config,
headers: { Authorization: `Bearer ${accessToken}` },
});
}
}
return Promise.reject(error);
}
);
}
async refresh() {
try {
const response = await this.api.post("/auth/refresh", {
refreshToken: window.localStorage.getItem("refreshToken"),
});
const accessToken = response.data.value.accessToken;
window.localStorage.setItem("accessToken", accessToken);
this.setAuthorization();
return accessToken;
} catch {
clearLocalstorage();
return null;
}
}
clear() {
clearLocalstorage();
this.setAuthorization();
}
}
function clearLocalstorage() {
window.localStorage.removeItem("accessToken");
window.localStorage.removeItem("refreshToken");
}
// 이름을 뭘로 해야할지..
export const apiSetting = new API();
export const api = apiSetting.api;
this.api.interceptors.response.use(
(res) => res,
async (error: AxiosError) => {
const { config, response } = error;
if (
response?.status === 401 &&
window.localStorage.getItem("accessToken")
) {
const accessToken = await this.refresh();
if (accessToken) {
return axios({
...config,
headers: { Authorization: `Bearer ${accessToken}` },
});
}
}
return Promise.reject(error);
}
);
this.api는 axios.create 로 만든 인스턴스이다.
this.api.interceptors.response.use() 메서드로 인터셉터를 등록 할 수 있는데, 첫번째 인자에는 요청이 성공했을 때 실행될 인터셉터이고, 두번째 인자로 요청이 실패했을 경우 실행될 인터셉터이다.
액세스 토큰 인증이 실패할 경우 서버에서 401 상태코드로 에러 응답을 보내는데, 에러응답 인터셉터에서 이 상태코드의 에러의 경우 토큰을 리프레시하고 다시 재요청을 보내면 된다.
Loading Comments...