Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions apps/web/src/app/mypage/_actions/logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { cookies } from 'next/headers';

import { deleteFcmToken } from '@/apis/deleteFcmToken';
import { serverApi } from '@/apis/server';
import { clearAuthCookies } from '@/app/mypage/_common/_actions/clearAuthCookies';
import { ENDPOINTS } from '@/consts/api';

const AUTH_COOKIE_NAMES = ['access_token', 'refresh_token', 'device_id'] as const;

export const logout = async () => {
const cookieStore = await cookies();
const deviceId = cookieStore.get('device_id')?.value;
Expand All @@ -26,7 +25,5 @@ export const logout = async () => {
// 백엔드 실패해도 로컬 쿠키는 삭제
}

AUTH_COOKIE_NAMES.forEach(cookieName => {
if (cookieStore.has(cookieName)) cookieStore.delete(cookieName);
});
await clearAuthCookies();
};
14 changes: 14 additions & 0 deletions apps/web/src/app/mypage/_common/_actions/clearAuthCookies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use server';

import { cookies } from 'next/headers';

const AUTH_COOKIE_NAMES = ['access_token', 'refresh_token', 'device_id'] as const;

/** 브라우저 httpOnly 인증 쿠키는 JS 로 지울 수 없어 서버 액션으로 폐기한다 */
export const clearAuthCookies = async () => {
const cookieStore = await cookies();

AUTH_COOKIE_NAMES.forEach(cookieName => {
if (cookieStore.has(cookieName)) cookieStore.delete(cookieName);
});
};
9 changes: 8 additions & 1 deletion apps/web/src/app/mypage/withdraw/_hooks/useDeleteMe.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { WEBBRIDGE_MESSAGE_TYPE } from '@piki/core';
import * as Sentry from '@sentry/nextjs';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';

import { clearAuthCookies } from '@/app/mypage/_common/_actions/clearAuthCookies';
import { ROUTES } from '@/consts/route';
import { isGlobalNetError } from '@/utils/apiError';
import { deleteCookie } from '@/utils/cookie';
Expand All @@ -17,14 +19,19 @@ export const useDeleteMe = () => {

const { mutate: deleteMeMutation, isPending: isDeleteMePending } = useMutation({
mutationFn: deleteMe,
onSuccess: () => {
onSuccess: async () => {
if (isWebview()) {
deleteCookie('access_token');
deleteCookie('refresh_token');

WebBridge.postMessage({ type: WEBBRIDGE_MESSAGE_TYPE.WEB_REQ_LOGOUT });
} else {
/** 웹인 경우 쿠키 삭제 */
await clearAuthCookies();
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Sentry.setUser(null);

queryClient.clear();
router.replace(ROUTES.ROOT);
},
Expand Down
14 changes: 8 additions & 6 deletions apps/web/src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ const handleTokenRefresh = async (request: NextRequest) => {
}
};

/** 세션 만료 신호로 진입한 로그인 - 토큰 폐기 후 페이지 진입 */
const handleSessionExpired = (request: NextRequest) => {
/** 세션 만료·탈퇴 신호로 진입한 로그인 - 토큰 폐기 후 페이지 진입 */
const handleAuthReset = (request: NextRequest) => {
/** 페이지 렌더링 시 죽은 토큰을 보지 않도록 남은 쿠키에서 삭제 */
const remainingCookies = request.cookies
.getAll()
Expand Down Expand Up @@ -255,10 +255,12 @@ export const proxy = async (request: NextRequest) => {

/** 퍼블릭 영역 */
if (routeType === 'PUBLIC') {
const isSessionExpired =
pathname === ROUTES.LOGIN &&
request.nextUrl.searchParams.get(QUERY_ACTION.KEY) === QUERY_ACTION.VALUE.SESSION_EXPIRED;
if (isSessionExpired) return handleSessionExpired(request);
const loginAction =
pathname === ROUTES.LOGIN ? request.nextUrl.searchParams.get(QUERY_ACTION.KEY) : null;
const isAuthReset =
loginAction === QUERY_ACTION.VALUE.SESSION_EXPIRED ||
loginAction === QUERY_ACTION.VALUE.WITHDRAWN_ACCOUNT;
if (isAuthReset) return handleAuthReset(request);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const needsRestore =
pathname === ROUTES.LOGIN &&
Expand Down
Loading