로그아웃 기능 추가

This commit is contained in:
2026-01-02 13:04:13 +09:00
parent 3ebd34d2de
commit 88b70011c5
3 changed files with 42 additions and 9 deletions

View File

@@ -55,11 +55,28 @@ export const register = async (data: RegisterData): Promise<{ message: string }>
// 로그아웃 API
export const logout = async (): Promise<void> => {
await axios.post('/auth/logout');
try {
// HttpOnly 쿠키 삭제를 위해 서버의 로그아웃 API를 GET 방식으로 호출
await axios.get('/auth/logout');
} catch (error) {
// 서버 로그아웃 실패하더라도 클라이언트는 정리 진행
}
// 로컬 스토리지 정리
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
document.cookie = 'access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/';
document.cookie = 'refresh_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/';
// 쿠키 정리
const cookieNames = ['access_token', 'refresh_token'];
const domain = window.location.hostname;
const paths = ['/', '/api']; // 가능한 경로들
cookieNames.forEach(name => {
paths.forEach(path => {
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}; domain=${domain}`;
});
});
};
// 토큰이 유효한지 확인

View File

@@ -19,12 +19,16 @@ import {
cilSettings,
cilTask,
cilUser,
cilAccountLogout,
} from '@coreui/icons'
import { useAuth } from 'src/hooks/useAuth'
import CIcon from '@coreui/icons-react'
import avatar8 from 'src/assets/images/avatars/8.jpg'
const AppHeaderDropdown = () => {
const { logout } = useAuth()
return (
<CDropdown variant="nav-item">
<CDropdownToggle className="py-0 pe-0" caret={false}>
@@ -84,9 +88,9 @@ const AppHeaderDropdown = () => {
</CBadge>
</CDropdownItem>
<CDropdownDivider />
<CDropdownItem href="#">
<CIcon icon={cilLockLocked} className="me-2" />
Lock Account
<CDropdownItem onClick={logout} style={{ cursor: 'pointer' }}>
<CIcon icon={cilAccountLogout} className="me-2" />
Logout
</CDropdownItem>
</CDropdownMenu>
</CDropdown>

View File

@@ -1,6 +1,6 @@
import React, { createContext, useReducer, useEffect } from 'react';
import { isTokenValid, getAccessTokenFromCookie, getUserFromToken, getRefreshTokenFromCookie, renewAccessToken } from 'src/axios/authService';
import { isTokenValid, getAccessTokenFromCookie, getUserFromToken, getRefreshTokenFromCookie, renewAccessToken, logout as apiLogout } from 'src/axios/authService';
// 사용자 타입 정의
export interface Member {
@@ -63,6 +63,9 @@ const authReducer = (state: AuthState, action: AuthAction): AuthState => {
};
case 'LOGOUT':
localStorage.removeItem('accessToken');
localStorage.removeItem('access_token');
localStorage.removeItem('refreshToken');
localStorage.removeItem('refresh_token');
return {
...state,
isAuthenticated: false,
@@ -72,6 +75,9 @@ const authReducer = (state: AuthState, action: AuthAction): AuthState => {
};
case 'AUTH_ERROR':
localStorage.removeItem('accessToken');
localStorage.removeItem('access_token');
localStorage.removeItem('refreshToken');
localStorage.removeItem('refresh_token');
return {
...state,
isAuthenticated: false,
@@ -114,8 +120,14 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
};
// 로그아웃 함수
const logout = () => {
dispatch({ type: 'LOGOUT' });
const logout = async () => {
try {
await apiLogout();
} catch (error) {
console.error('Logout failed:', error);
} finally {
dispatch({ type: 'LOGOUT' });
}
};
// 초기 인증 상태 확인