Skip to content

Commit afbdf70

Browse files
committed
fix(company): redirect to login on auth errors
1 parent 1230ca5 commit afbdf70

1 file changed

Lines changed: 109 additions & 66 deletions

File tree

apps/company/src/apis/axios.ts

Lines changed: 109 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,53 @@
1-
import axios, { AxiosError } from "axios";
1+
import axios, { AxiosError, InternalAxiosRequestConfig } from "axios";
22
import { Cookies } from "react-cookie";
3-
import { reissueToken } from "./auth";
3+
import { ReissueToken } from "./auth";
4+
import * as Sentry from "@sentry/nextjs";
5+
6+
type ErrorResponseData = {
7+
message?: string;
8+
status?: number;
9+
};
10+
11+
type RetryableRequestConfig = InternalAxiosRequestConfig & {
12+
_retry?: boolean;
13+
};
414

515
export const instance = axios.create({
616
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
7-
timeout: 10_000,
17+
timeout: 10_000
818
});
919

1020
const cookie = new Cookies();
1121

22+
const clearAuthCookies = () => {
23+
cookie.remove("access_token", { path: "/" });
24+
cookie.remove("refresh_token", { path: "/" });
25+
cookie.remove("authority", { path: "/" });
26+
};
27+
28+
const redirectTo = (path: string) => {
29+
if (typeof window === "undefined") {
30+
return;
31+
}
32+
33+
if (window.location.pathname !== path) {
34+
window.location.href = path;
35+
}
36+
};
37+
1238
instance.interceptors.request.use(
1339
config => {
1440
const accessToken = cookie.get("access_token");
1541
const returnConfig = {
16-
...config,
42+
...config
1743
};
44+
45+
returnConfig.headers = returnConfig.headers ?? {};
46+
1847
if (accessToken) {
19-
returnConfig.headers!.Authorization = `Bearer ${accessToken}`;
48+
returnConfig.headers.Authorization = `Bearer ${accessToken}`;
2049
}
50+
2151
return returnConfig;
2252
},
2353
(error: AxiosError) => {
@@ -27,73 +57,86 @@ instance.interceptors.request.use(
2757

2858
instance.interceptors.response.use(
2959
async response => response,
30-
async (error: AxiosError<AxiosError>) => {
60+
async (error: AxiosError<ErrorResponseData>) => {
3161
console.error(error);
32-
if (axios.isAxiosError(error) && error.response) {
33-
const {
34-
config,
35-
response: { data },
36-
} = error;
37-
const refreshToken = cookie.get("refresh_token");
38-
const { response, message } = error;
39-
40-
if (response.data.status && response.data.status > 500) {
41-
window.location.href = "/serverCheck";
42-
throw error;
43-
}
62+
Sentry.captureException(error);
4463

45-
if (response.data.status === null) {
46-
return;
47-
}
64+
if (!axios.isAxiosError(error) || !error.response) {
65+
throw error;
66+
}
67+
68+
const { config, response } = error;
69+
const refreshToken = cookie.get("refresh_token");
70+
const status = response.status ?? response.data?.status;
71+
const responseMessage = response.data?.message;
72+
Sentry.captureMessage(responseMessage ?? error.message);
73+
const originalRequest = config as RetryableRequestConfig | undefined;
74+
const isReissueRequest = originalRequest?.url?.includes("/auth/reissue");
75+
const isAuthError =
76+
status === 401 ||
77+
status === 403 ||
78+
responseMessage === "Invalid Token" ||
79+
responseMessage === "Token Expired";
80+
81+
if ((response.data?.status ?? response.status) >= 500) {
82+
redirectTo("/serverCheck");
83+
throw error;
84+
}
85+
86+
if (!isAuthError) {
87+
throw error;
88+
}
89+
90+
if (!originalRequest || originalRequest._retry || isReissueRequest) {
91+
clearAuthCookies();
92+
redirectTo("/");
93+
throw error;
94+
}
95+
96+
if (!refreshToken) {
97+
clearAuthCookies();
98+
redirectTo("/");
99+
throw error;
100+
}
101+
102+
originalRequest._retry = true;
103+
cookie.remove("access_token", { path: "/" });
104+
105+
try {
106+
const res = await ReissueToken(refreshToken);
107+
const accessExpired = new Date(res.access_expires_at);
108+
const refreshExpired = new Date(res.refresh_expires_at);
109+
110+
cookie.set("access_token", res.access_token, {
111+
expires: accessExpired,
112+
path: "/"
113+
});
114+
cookie.set("refresh_token", res.refresh_token, {
115+
expires: refreshExpired,
116+
path: "/"
117+
});
118+
cookie.set("authority", res.authority, { path: "/" });
119+
120+
originalRequest.headers = originalRequest.headers ?? {};
121+
originalRequest.headers.Authorization = `Bearer ${res.access_token}`;
122+
123+
return instance(originalRequest);
124+
} catch (reissueError) {
125+
const reissueAxiosError = reissueError as AxiosError<ErrorResponseData>;
126+
const reissueStatus =
127+
reissueAxiosError.response?.status ??
128+
reissueAxiosError.response?.data?.status;
48129

49130
if (
50-
response.data.message === "Invalid Token" ||
51-
response.data.message === "Token Expired" ||
52-
message === "Request failed with status code 403"
131+
reissueStatus === 404 ||
132+
reissueStatus === 401 ||
133+
reissueStatus === 403
53134
) {
54-
const originalRequest = config;
55-
56-
if (refreshToken) {
57-
cookie.remove("access_token");
58-
reissueToken(refreshToken)
59-
.then(res => {
60-
const accessExpired = new Date(res.access_expires_at);
61-
const refreshExpired = new Date(res.refresh_expires_at);
62-
63-
cookie.set("access_token", res.access_token, {
64-
expires: accessExpired,
65-
path: "/",
66-
});
67-
cookie.set("refresh_token", res.refresh_token, {
68-
expires: refreshExpired,
69-
path: "/",
70-
});
71-
cookie.set("authority", res.authority);
72-
if (originalRequest!.headers) {
73-
originalRequest!.headers.Authorization = `Bearer ${res.access_token}`;
74-
}
75-
return axios(originalRequest!);
76-
})
77-
.catch((err: AxiosError<AxiosError>) => {
78-
const { response: errorResponse } = err;
79-
80-
if (
81-
errorResponse?.data.status === 404 ||
82-
errorResponse?.data.status === 401
83-
) {
84-
cookie.remove("access_token");
85-
cookie.remove("refresh_token");
86-
window.location.href = "/";
87-
}
88-
});
89-
} else {
90-
cookie.remove("access_token");
91-
cookie.remove("refresh_token");
92-
window.location.href = "/";
93-
}
94-
} else {
95-
throw error;
135+
clearAuthCookies();
136+
redirectTo("/");
96137
}
138+
139+
throw reissueError;
97140
}
98141
}
99142
);

0 commit comments

Comments
 (0)