Skip to content

Commit

Permalink
feat : 새로고침 시 로그인, 로그아웃 상태 관리 추가 (#178)
Browse files Browse the repository at this point in the history
* feat : 로고 메인으로 연결

* feat : Layout에서 로그인 상태를 처리할 수 있는 로직 작성

* feat : 로그아웃 & AuthProvider 추가

* feat : 헤더 로그아웃 아이템 추가
  • Loading branch information
cmlim0070 authored Nov 5, 2024
1 parent 71b8d41 commit ece2ec1
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 6 deletions.
60 changes: 60 additions & 0 deletions src/app/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useAuthStore } from '@/features/login/hooks/useAuthStore';
import useLogout from '@/features/login/hooks/useLogout';
import { decodeJwtPayload } from '@/features/login/util/decodeJwtPayload ';
import useLocalStorage from '@/shared/hooks/useLocalStorage';
import { ReactNode, useEffect } from 'react';

interface AuthLayoutProps {
children: ReactNode;
}

interface userType {
email: string;
username: string;
}

// 토큰 만료 체크 테스트 함수

// 성공
function TestVerifyTokenTrue(token: string) {
return true;
}
// 실패
function TestVerifyTokenFalse(token: string) {
return false;
}

const AuthProvider = ({ children }: AuthLayoutProps) => {
const { setUserInfo } = useAuthStore();
const { storedValue: token } = useLocalStorage<string>('token', '');
const { handleLogout } = useLogout();

useEffect(() => {
const initializeAuth = async () => {
if (token) {
try {
// await axios.get('/api/verify-token');
if (TestVerifyTokenTrue(token)) {
const payload = decodeJwtPayload<userType>(token);
if (payload) {
console.log('토큰 유효');
setUserInfo(payload.email, payload.username, true);
}
} else {
console.log('토큰 만료');
handleLogout();
}
} catch {
console.log('토큰 없음');
handleLogout();
}
}
};
initializeAuth();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return children;
};

export default AuthProvider;
8 changes: 5 additions & 3 deletions src/app/layout/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import Header from '@/widgets/header/ui/Header';
import React from 'react';
import { Outlet } from 'react-router-dom';
import AuthProvider from '../AuthProvider';

const Layout = () => {
return (
<div>
<Header />
<Outlet />
<AuthProvider>
<Header />
<Outlet />
</AuthProvider>
</div>
);
};
Expand Down
25 changes: 25 additions & 0 deletions src/features/login/hooks/useLogout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useToastStore } from '@/features/Toast/hooks/useToastStore';
import useLocalStorage from '@/shared/hooks/useLocalStorage';
import { useNavigate } from 'react-router-dom';
import { useAuthStore } from './useAuthStore';

const useLogout = () => {
const navigate = useNavigate();
const { addToast } = useToastStore();
const { setValue: setToken } = useLocalStorage<string>('token', '');
const { setUserInfo } = useAuthStore();

const handleLogout = () => {
try {
setToken('');
setUserInfo('', '', false);
addToast('로그아웃되었습니다.', 'success');
navigate('/login');
} catch (error) {
addToast('로그아웃 처리에 실패했어요.', 'error');
}
};
return { handleLogout };
};

export default useLogout;
18 changes: 15 additions & 3 deletions src/widgets/header/ui/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@ import { Container, Logo, Nav, NavItem, LoginButton } from './Header.styled';
import LogoImage from '@/shared/assets/logo.svg';
import { useAuthStore } from '@/features/login/hooks/useAuthStore';
import { Link, useNavigate } from 'react-router-dom';
import useLogout from '@/features/login/hooks/useLogout';

const Header = () => {
const navigate = useNavigate();
const { email, userName, isLoggedin, setUserInfo } = useAuthStore();
const { userName, isLoggedin } = useAuthStore();
const { handleLogout } = useLogout();

const handleLogoutClick = (e: React.MouseEvent) => {
e.preventDefault();
handleLogout();
};

return (
<Container>
<Logo>
<img src={LogoImage} alt="logo" />
<Link to="/">
<img src={LogoImage} alt="logo" />
</Link>
</Logo>
<Nav>
<Link to="/">
Expand All @@ -26,10 +36,12 @@ const Header = () => {
<NavItem>마이페이지</NavItem>
</Link>
)}
{!isLoggedin && (
{!isLoggedin ? (
<Link to="/login">
<NavItem>로그인</NavItem>
</Link>
) : (
<NavItem onClick={handleLogoutClick}>로그아웃</NavItem>
)}
</Nav>
</Container>
Expand Down

0 comments on commit ece2ec1

Please sign in to comment.