Skip to content

Commit

Permalink
feat: refresh token 쿠키에 저장
Browse files Browse the repository at this point in the history
  • Loading branch information
chlwlstlf committed Jan 17, 2025
1 parent 06b2a48 commit 3a6fd57
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 35 deletions.
45 changes: 22 additions & 23 deletions frontend/src/apis/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,12 @@ const processQueue = (error: Error | null = null, token: string | null = null) =
};

const refreshAccessToken = async (): Promise<string | undefined> => {
const refreshToken = localStorage.getItem("refreshToken");

const response = await fetch(`${serverUrl}${API_ENDPOINTS.REFRESH}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ refreshToken }),
credentials: "include",
});

const text = await response.text();
Expand All @@ -36,7 +34,7 @@ const refreshAccessToken = async (): Promise<string | undefined> => {
const newAccessToken = response.headers.get("Authorization");

if (!response.ok) {
if (response.status === 401) {
if (response.status === 401 && data.exceptionType === "TOKEN_EXPIRED") {
const error = new AuthorizationError(data.message || MESSAGES.ERROR.POST_REFRESH);
processQueue(error, null);
isRefreshing = false;
Expand All @@ -55,24 +53,6 @@ const refreshAccessToken = async (): Promise<string | undefined> => {
}
};

const createRequestInit = (
method: Method,
headers: Record<string, string>,
body: object | null,
): RequestInit => {
const token = localStorage.getItem("accessToken");

return {
method,
headers: {
...headers,
Authorization: token ? `Bearer ${token}` : "",
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : null,
};
};

const fetchWithToken = async (
endpoint: string,
requestInit: RequestInit,
Expand All @@ -86,7 +66,7 @@ const fetchWithToken = async (
let text = await response.text();
let data = text ? JSON.parse(text) : null;

if (response.status === 401 && data.message === "토큰이 만료되었습니다.") {
if (response.status === 401 && data.exceptionType === "TOKEN_EXPIRED") {
if (isRefreshing) {
new Promise<string>((resolve, reject) => {
failedQueue.push({ resolve, reject });
Expand Down Expand Up @@ -128,6 +108,25 @@ const fetchWithToken = async (
return text ? data : response;
};

const createRequestInit = (
method: Method,
headers: Record<string, string>,
body: object | null,
): RequestInit => {
const token = localStorage.getItem("accessToken");

return {
method,
headers: {
...headers,
Authorization: token ? `Bearer ${token}` : "",
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : null,
credentials: "include",
};
};

const apiClient = {
get: ({ endpoint, headers = {}, errorMessage = "" }: ApiProps) =>
apiClient.request({ method: "GET", endpoint, headers, errorMessage }),
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/apis/auth.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const postLogin = async (code: string): Promise<UserInfoResponse> => {
"Content-Type": "application/json",
},
body: JSON.stringify({ code }),
credentials: "include",
});

if (!response.ok) {
Expand All @@ -23,15 +24,14 @@ export const postLogin = async (code: string): Promise<UserInfoResponse> => {
const accessToken = response.headers.get("Authorization");

const authBody = text ? JSON.parse(text) : response;
const refreshToken = authBody.refreshToken;
const userInfo = authBody.userInfo as UserInfo;
const memberRole = authBody.memberRole as string;

if (!accessToken) {
throw new Error(MESSAGES.ERROR.POST_LOGIN);
}

return { accessToken, refreshToken, userInfo, memberRole };
return { accessToken, userInfo, memberRole };
};

export const postLogout = async (): Promise<void> => {
Expand Down
12 changes: 2 additions & 10 deletions frontend/src/hooks/mutations/useMutateAuth.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import useMutateHandlers from "./useMutateHandlers";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useMutation } from "@tanstack/react-query";
import { UserInfo } from "@/@types/userInfo";
import { postLogin, postLogout } from "@/apis/auth.api";
import QUERY_KEYS from "@/apis/queryKeys";

export interface UserInfoResponse {
accessToken: string;
refreshToken: string;
userInfo: UserInfo;
memberRole: string;
}

const useMutateAuth = () => {
const { handleMutateError } = useMutateHandlers();
const queryClient = useQueryClient();

const postLoginMutation = useMutation({
mutationFn: (code: string) => postLogin(code),
onSuccess: ({ accessToken, refreshToken, userInfo, memberRole }: UserInfoResponse) => {
onSuccess: ({ accessToken, userInfo, memberRole }: UserInfoResponse) => {
localStorage.setItem("accessToken", accessToken);
localStorage.setItem("refreshToken", refreshToken);
localStorage.setItem("userInfo", JSON.stringify(userInfo));
localStorage.setItem("memberRole", memberRole);
},
Expand All @@ -32,10 +28,6 @@ const useMutateAuth = () => {
const postLogoutMutation = useMutation({
mutationFn: () => postLogout(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.PARTICIPATED_ROOM_LIST] });
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.PROGRESS_ROOM_LIST] });
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.OPENED_ROOM_LIST] });
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.CLOSED_ROOM_LIST] });
localStorage.clear();
window.location.replace("/");
},
Expand Down

0 comments on commit 3a6fd57

Please sign in to comment.