Skip to content

Commit

Permalink
Merge pull request #63 from potenday-project:로그인/로그아웃-핸들러-개선
Browse files Browse the repository at this point in the history
로그인/로그아웃-핸들러-개선
  • Loading branch information
jobkaeHenry authored Nov 30, 2023
2 parents eef2d79 + 9f4bbd8 commit 91064a8
Show file tree
Hide file tree
Showing 15 changed files with 81 additions and 49 deletions.
15 changes: 3 additions & 12 deletions client/src/app/(protectedRoute)/user/setting/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import {
styled,
} from "@mui/material";
import PostSeeMoreIcon from "@/assets/icons/PostSeeMoreIcon.svg";
import { axiosBff } from "@/libs/axios";
import { LOGOUT_BFF } from "@/const/serverPath";
import useLogoutMutation from "@/queries/auth/useLogoutMutation";

const SettingPage = () => {
const { data: myInfo } = useMyInfoQuery();
const { mutate: logoutHandler } = useLogoutMutation();

return (
<>
Expand Down Expand Up @@ -67,16 +67,7 @@ const SettingPage = () => {
</PaddingPaper>
<PaddingPaper>
<Typography variant="subtitle2">계정</Typography>
<Button
color="secondary"
onClick={() => {
// FIXME 추후 수정해야하는 로그아웃로직
localStorage.removeItem("accessToken");
axiosBff.post(LOGOUT_BFF).then((res) => {
location.reload()
});
}}
>
<Button color="secondary" onClick={() => logoutHandler()}>
로그아웃
</Button>
</PaddingPaper>
Expand Down
1 change: 0 additions & 1 deletion client/src/components/ModalWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const ModalWrapper = ({ children, disableBox }: ModalInterface) => {
p: disableBox ? 0 : 4,
maxWidth: "90%",
maxHeight: "90%",
overflowY: "auto",
}}
>
<>{children}</>
Expand Down
3 changes: 2 additions & 1 deletion client/src/components/SearchHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ const SearchHistory = ({ storageKey, onClick }: SearchHistoryProps) => {
전체 삭제
</Button>
</Stack>
<Stack>
<Stack component="ul">
{searchHistory.map((keyword) => (
<Stack
key={keyword}
component="li"
onClick={onClick}
direction="row"
justifyContent="space-between"
Expand Down
17 changes: 17 additions & 0 deletions client/src/hooks/useAxiosPrivate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import axios from "@/libs/axios";
import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage";

const useAxiosPrivate = () => {
axios.interceptors.request.use(
(config) => {
if (config.headers) {
config.headers.Authorization = getTokenFromLocalStorage();
}
return config;
},
(error) => Promise.reject(error)
);
return axios;
};

export default useAxiosPrivate;
16 changes: 2 additions & 14 deletions client/src/libs/axios.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage";
import axios from "axios";

axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "x-CSRFToken";

/**
* 토큰을 싣고가는 요청
*/
export const axiosPrivate = axios.create({
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
headers: {
"Content-Type": "application/json",
Authorization: getTokenFromLocalStorage(),
},
});

/**
* 쿠키없이 가는 요청
*/
Expand All @@ -25,5 +13,5 @@ export default axios.create({ baseURL: process.env.NEXT_PUBLIC_BASE_URL });
*/
export const axiosBff = axios.create({
baseURL: process.env.NEXT_PUBLIC_CLIENT_BASE_URL,
withCredentials:true
});
withCredentials: true,
});
3 changes: 2 additions & 1 deletion client/src/queries/attach/useDeleteAttachMutation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { REMOVE_FILE } from "@/const/serverPath";
import { axiosPrivate } from "@/libs/axios";
import useAxiosPrivate from "@/hooks/useAxiosPrivate";
import { useErrorHandler } from "@/utils/errorHandler";
import { useMutation, useQueryClient } from "@tanstack/react-query";

Expand All @@ -20,6 +20,7 @@ const useDeleteAttachMutation = () => {
};

export const deleteAttachMutationFn = async (attachNo: string) => {
const axiosPrivate = useAxiosPrivate();
const { data } = await axiosPrivate.delete(REMOVE_FILE(attachNo));
return data;
};
Expand Down
3 changes: 2 additions & 1 deletion client/src/queries/attach/useNewAttachMutation.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { axiosPrivate } from "@/libs/axios";
import { ATTACH_FILE, ATTACH_FILE_ResourceType } from "@/const/serverPath";
import { useErrorHandler } from "./../../utils/errorHandler";
import { getPostListInfiniteQueryKey } from "./../post/useGetPostListInfiniteQuery";
import { postDetailQueryKey } from "../post/useGetPostDetailQuery";
import { MyInfoQueryKeys } from "../auth/useMyInfoQuery";
import { UserInfoQueryKey } from "../user/useUserInfoQuery";
import useAxiosPrivate from "@/hooks/useAxiosPrivate";

export const useNewAttachMutation = () => {
const errorHandler = useErrorHandler();
Expand Down Expand Up @@ -59,6 +59,7 @@ export const postImageFn = async (
file: File,
{ type, pk }: NewAttatchRequestUrl
) => {
const axiosPrivate = useAxiosPrivate()
const formData = new FormData();
formData.append("image", file);

Expand Down
1 change: 0 additions & 1 deletion client/src/queries/auth/useLoginMutation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const useLoginMutation = () => {
onSuccess: async ({ token }) => {
localStorage?.setItem("accessToken", token);
queryClient.invalidateQueries({ queryKey: MyInfoQueryKeys.all });
router.refresh();
router.push(HOME);
},
onError: (error) => errorHandler(error),
Expand Down
26 changes: 26 additions & 0 deletions client/src/queries/auth/useLogoutMutation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import HOME from "@/const/clientPath";
import { LOGOUT_BFF } from "@/const/serverPath";
import { axiosBff } from "@/libs/axios";
import { useGlobalSnackbarStore } from "@/store/useGlobalSnackbarStore";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useRouter } from "next/navigation";

const useLogoutMutation = () => {
const router = useRouter();
const queryClient = useQueryClient();

const fireToast = useGlobalSnackbarStore((state) => state.fireToast);

return useMutation({
mutationFn: logoutFn,
onSuccess: () => {
localStorage.removeItem("accessToken");
queryClient.removeQueries();
router.push(HOME);
fireToast("로그아웃이 완료되었습니다");
},
});
};
const logoutFn = () => axiosBff.post(LOGOUT_BFF);

export default useLogoutMutation;
7 changes: 3 additions & 4 deletions client/src/queries/auth/useMyInfoQuery.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";
import { MY_INFO } from "@/const/serverPath";
import { axiosPrivate } from "@/libs/axios";
import useAxiosPrivate from "@/hooks/useAxiosPrivate";
import { MyInfoInterface } from "@/types/auth/myInfo";
import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage";
import { useQuery } from "@tanstack/react-query";
Expand All @@ -16,9 +16,8 @@ export const getMyInfoByLocalStorage = async () => {
if (!accessToken) {
return null;
}
const { data } = await axiosPrivate.get<MyInfoInterface>(MY_INFO, {
headers: { Authorization: accessToken },
});
const axiosPrivate = useAxiosPrivate();
const { data } = await axiosPrivate.get<MyInfoInterface>(MY_INFO);
return data;
};

Expand Down
8 changes: 5 additions & 3 deletions client/src/queries/post/useDeletePostMutation.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { REMOVE_POST } from "@/const/serverPath";
import { axiosPrivate } from "@/libs/axios";
import { useMutation } from "@tanstack/react-query";
import { useInvalidatePostList } from "./useGetPostListInfiniteQuery";
import { useErrorHandler } from "@/utils/errorHandler";
import useAxiosPrivate from "@/hooks/useAxiosPrivate";

export const useDeletePostMutation = () => {
const invalidatePreviousData = useInvalidatePostList();
Expand All @@ -18,5 +18,7 @@ export const useDeletePostMutation = () => {
});
};

export const deletePostFn = (pk: number) =>
axiosPrivate.delete(REMOVE_POST(pk));
export const deletePostFn = (pk: number) => {
const axiosPrivate = useAxiosPrivate();
return axiosPrivate.delete(REMOVE_POST(pk));
};
5 changes: 3 additions & 2 deletions client/src/queries/post/useGetPostListInfiniteQuery.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query";
import axios from "@/libs/axios";
import { PostInterface } from "@/types/post/PostInterface";
import { AxiosRequestConfig } from "axios";
import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage";
import { POST_LIST } from "@/const/serverPath";
import useAxiosPrivate from "@/hooks/useAxiosPrivate";

export interface UseGetPostListQueryInterface extends GetPostListOptions {
initialData?: AugmentedGetPostListResponse;
Expand Down Expand Up @@ -81,7 +81,8 @@ export const getPostListQueryFn = async ({
}: GetPostListOptions & {
headers?: AxiosRequestConfig<any>["headers"];
}): Promise<AugmentedGetPostListResponse> => {
const { data } = await axios.get<GetPostListResponse>(POST_LIST, {
const axiosPrivate = useAxiosPrivate()
const { data } = await axiosPrivate.get<GetPostListResponse>(POST_LIST, {
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
params: { page, size, searchKeyword, searchUserNos },
headers,
Expand Down
5 changes: 1 addition & 4 deletions client/src/queries/post/useUnLikePostMutation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,4 @@ export const useLikePostMutationFn = async (id: PostInterface["postNo"]) => {
return data;
};

export default useLikePostMutation;
function postDetailUpdator(arg0: string) {
throw new Error("Function not implemented.");
}
export default useLikePostMutation;
3 changes: 2 additions & 1 deletion client/src/queries/user/usePatchUserInfoMutation.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { PATCH_USER_INFO } from "@/const/serverPath";
import { axiosPrivate } from "@/libs/axios";
import { UserInfoInterface } from "@/types/user/userInfoInterface";
import { useErrorHandler } from "@/utils/errorHandler";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { UserInfoQueryKey } from "./useUserInfoQuery";
import { useMyInfoQuery } from "../auth/useMyInfoQuery";
import useAxiosPrivate from "@/hooks/useAxiosPrivate";

const usePatchUserInfoMutation = () => {
const errorHandler = useErrorHandler();
Expand All @@ -26,6 +26,7 @@ const usePatchUserInfoMutation = () => {
export const patchUserInfoMutateFn = async (
info: Partial<UserInfoInterface>
) => {
const axiosPrivate = useAxiosPrivate();
const { data } = await axiosPrivate.patch(PATCH_USER_INFO, { ...info });
return data;
};
Expand Down
17 changes: 13 additions & 4 deletions client/src/utils/errorHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,30 @@
import { useGlobalSnackbarStore } from "@/store/useGlobalSnackbarStore";
import { isAxiosError } from "axios";
import { useCallback } from "react";
import getTokenFromLocalStorage from "./getTokenFromLocalStorage";
import { useGlobalLoadingStore } from "@/store/useGlobalLoadingStore";

/**
* Axios 에러의 status 코드를 판별해 적절한 토스트팝업을 표출해주는 함수를 리런하는 훅
* @returns errorHandler (error)=>void
*/
export const useErrorHandler = () => {
const fireToast = useGlobalSnackbarStore((state) => state.fireToast);

const setLoading = useGlobalLoadingStore((state) => state.setLoading);
const errorHandler = useCallback((error: Error) => {
setLoading(false);
if (isAxiosError(error) && error.response) {
switch (error.response.status) {
case 401:
fireToast("로그인 후 이용 가능합니다");
// 토큰이 만료된 경우가 대부분이므로 토큰제거
localStorage.removeItem('accessToken')
// 토큰이 만료된 경우
if (getTokenFromLocalStorage()) {
fireToast("세션이 만료되었습니다.");
localStorage.removeItem("accessToken");
} else fireToast("로그인 후 이용 가능합니다");
return;
case 403:
fireToast("권한이 없습니다");
return;
}
}
}, []);
Expand Down

0 comments on commit 91064a8

Please sign in to comment.