Skip to content

Commit

Permalink
Merge pull request #141 from depromeet/feature/#140
Browse files Browse the repository at this point in the history
Feature/#140
  • Loading branch information
YOOJS1205 authored Jan 28, 2024
2 parents a0c8803 + d11b6e7 commit db784f3
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 4 deletions.
4 changes: 4 additions & 0 deletions public/assets/icon16/arrow_square_16.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/assets/icon24/right_arrow_24.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 22 additions & 4 deletions src/api/api-config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import axios from 'axios';
import Cookies from 'js-cookie';

import { TOKEN_REFRESH_URL } from '@constants/endpoint';
import { getTokenRefresh } from '@utils/getTokenRefresh';
import { TOKEN_REFRESH_URL, LOGOUT_URL } from '@constants/endpoint';
import { getTokenRefresh, logout } from '@utils/auth';

type Method = 'get' | 'post' | 'put' | 'delete' | 'patch';

Expand Down Expand Up @@ -62,6 +62,11 @@ axiosInstance.interceptors.request.use(
delete config.headers['Authorization'];
}

// NOTE: 로그아웃 요청 시 헤더 변경
if (config.url === LOGOUT_URL) {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
}

return config;
},
function (error) {
Expand All @@ -88,12 +93,25 @@ axiosInstance.interceptors.response.use(
const refreshToken = Cookies.get('refreshToken');

// NOTE: 토큰 재발급 요청
if (response.data.code === 401 && refreshToken) {
if (
config.url !== TOKEN_REFRESH_URL &&
response.data.code === 401 &&
refreshToken
) {
const { data } = await getTokenRefresh();
Cookies.set('accessToken', data.accessToken);
config.headers['Authorization'] = data.accessToken;
return axios(config);
}

// NOTE: 토큰 재발급 요청이 유효하지 않으면, 쿠키의 토큰을 삭제하고 로그아웃 처리. 로그인 페이지로 이동
if (config.url === TOKEN_REFRESH_URL && response.data.code === 401) {
Cookies.remove('accessToken');
Cookies.remove('refreshToken');
logout();

window.location.href = '/login';
}
return axios(config);
},
);

Expand Down
16 changes: 16 additions & 0 deletions src/app/settings/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Header from '@components/common/Header';

interface TermsLayoutProps {
children: React.ReactNode;
}

export default function layout({ children }: TermsLayoutProps) {
return (
<div>
<Header>
<p className="body-16-bold">설정</p>
</Header>
{children}
</div>
);
}
41 changes: 41 additions & 0 deletions src/app/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client';

import { useRouter } from 'next/navigation';

import { SETTINGS, Setting } from '@constants/settings';
import RightArrowIcon from 'public/assets/icon24/right_arrow_24.svg';
import ArrowSquareIcon from 'public/assets/icon16/arrow_square_16.svg';
import { useLogout } from '@hooks/api/useLogout';

export default function Page() {
const { push } = useRouter();
const { mutate: logout } = useLogout();

const handleClickSettingItem = (setting: Setting) => () => {
if (setting.url) {
push(setting.url);
}

if (setting.title === '로그아웃') {
logout();
}
};

return (
<ul className="pt-[56px]">
{SETTINGS.map((setting, index) => (
<li
key={index}
className="flex justify-between items-center py-[8px] pl-[24px] pr-[16px] h-[56px] cursor-pointer border-b-[1px] border-gray-100"
onClick={handleClickSettingItem(setting)}
>
<div className="flex gap-[4px] items-center">
<p className="body-16-bold">{setting.title}</p>
{setting.url && <ArrowSquareIcon />}
</div>
{setting.url && <RightArrowIcon />}
</li>
))}
</ul>
);
}
1 change: 1 addition & 0 deletions src/constants/endpoint.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const TOKEN_REFRESH_URL = '/api/v1/auth/token/reissue';
export const LOGOUT_URL = '/api/v1/auth/logout';
25 changes: 25 additions & 0 deletions src/constants/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export interface Setting {
url?: string;
title: string;
}

export const SETTINGS: Setting[] = [
{
url: '/service-terms',
title: '이용약관',
},
{
url: '/privacy-policy',
title: '개인정보처리방침',
},
{
url: '/location-terms',
title: '위치기반 서비스 이용약관',
},
{
title: '로그아웃',
},
{
title: '회원탈퇴',
},
];
19 changes: 19 additions & 0 deletions src/hooks/api/useLogout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useMutation, UseMutationResult } from '@tanstack/react-query';
import { AxiosError } from 'axios';
import Cookies from 'js-cookie';
import { useRouter } from 'next/navigation';

import { logout } from '@utils/auth';

export const useLogout = (): UseMutationResult<void, AxiosError, void> => {
const { push } = useRouter();
return useMutation({
mutationKey: ['logout'],
mutationFn: logout,
onSuccess: () => {
Cookies.remove('accessToken');
Cookies.remove('refreshToken');
push('/login');
},
});
};
2 changes: 2 additions & 0 deletions src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export function middleware(request: NextRequest) {
url.pathname = '/login';
}

url.search = '';

const response = NextResponse.redirect(url);

return response;
Expand Down
4 changes: 4 additions & 0 deletions src/utils/getTokenRefresh.ts → src/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ export const getTokenRefresh = async (): Promise<
> => {
return await axiosRequest('post', '/api/v1/auth/token/reissue');
};

export const logout = async (): Promise<void> => {
return axiosRequest('post', '/api/v1/auth/logout');
};

0 comments on commit db784f3

Please sign in to comment.