(1) 기본 페이지, 컴포넌트 구성
페이지
Home, Signin, Signup, Profile, TestPage, TestResultPage
컴포넌트
Layout, AuthForm, TestForm, TestResultList, TestResultItem
(2) 레이아웃 컴포넌트 만들기
레이아웃을 PublicLayout과 PrivateLayout으로 분리하여 만들었다.
// PublicLayout
const PublicLayout = () => {
return (
<>
<Link to="/signin">로그인</Link>
</>
);
};
// PrivateLayout
const PrivateLayout = () => {
const { logout } = useContext(AuthContext);
const navigate = useNavigate();
const handleLogout = () => {
const confirmLogout = window.confirm("정말로 로그아웃 하시겠습니까?");
if (confirmLogout) {
logout();
navigate("/");
}
};
return (
<>
<Link to="/profile">프로필</Link>
<Link to="/testpage">테스트</Link>
<Link to="/testresult">결과보기</Link>
<button onClick={handleLogout}>로그아웃</button>
</>
);
};
// Layout
const Layout = () => {
const { isAuthenticated } = useContext(AuthContext);
return (
<div>
<header>
<Link to="/">홈</Link>
{isAuthenticated ? <PrivateLayout /> : <PublicLayout />}
</header>
<main>
<Outlet />
</main>
</div>
);
};
(3) 로그인 및 회원가입 구현
// 회원가입
const SignUp = () => {
return (
<>
<AuthForm />
</>
);
};
const AuthForm = () => {
const navigate = useNavigate();
const [formData, setFormData] = useState({
id: "",
password: "",
nickname: "",
});
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await axios.post(
`${API_URL}/register`,
{
id: formData.id,
password: formData.password,
nickname: formData.nickname,
}
);
const data = response.data;
if (data.success) {
navigate("/signin");
} else {
alert("회원가입 실패");
}
} catch (error) {
console.error("회원가입 에러 :", error);
alert("회원가입 실패");
}
};
return (
<div>
<h1>회원가입</h1>
<form onSubmit={handleSubmit}>
<input
name="id"
type="text"
placeholder="아이디 입력"
value={formData.id}
onChange={handleChange}
/>
<input
name="password"
type="password"
placeholder="비밀번호 입력"
value={formData.password}
onChange={handleChange}
/>
<input
name="nickname"
type="text"
placeholder="닉네임 입력"
value={formData.nickname}
onChange={handleChange}
/>
<button type="submit">회원가입</button>
</form>
<p>
이미 계정이 있으신가요?{" "}
<button onClick={() => navigate("/signin")}>로그인</button>
</p>
</div>
);
};
// 로그인
const SignIn = () => {
const [id, setId] = useState("");
const [password, setPassword] = useState("");
const { login } = useContext(AuthContext);
const navigate = useNavigate();
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await axios.post(
`${API_URL}/login`,
{
id,
password,
}
);
const data = response.data;
if (data.success) {
login(data.accessToken);
navigate("/profile");
} else {
alert("로그인에 실패했습니다.");
}
} catch (error) {
console.error("Login error :", error);
alert("로그인에 실패했습니다.");
}
};
return (
<div>
<h3>SignIn</h3>
<form onSubmit={handleSubmit}>
<input type="text" value={id} onChange={(e) => setId(e.target.value)} />
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">로그인</button>
</form>
<p>
계정이 없으신가요?
<button onClick={() => navigate("/signup")}>회원가입</button>
</p>
</div>
);
};
(4) 라우터 설정(Private, Public 페이지 분리)
PublicRoute, PrivateRoute 생성 후 로그인된 사용자만 특정 페이지에 접근 할 수 있도록 하기
// PublicRoute
const PublicRoute = () => {
const { isAuthenticated } = useContext(AuthContext);
return isAuthenticated ? <Navigate to="/" /> : <Outlet />;
};
// PrivateRoute
const PrivateRoute = () => {
const { isAuthenticated } = useContext(AuthContext);
return !isAuthenticated ? <Navigate to="/signin" /> : <Outlet />;
};
// Router
const AppRouter = () => {
return (
<Router>
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<Home />} />
<Route element={<PublicRoute />}>
<Route path="/signin" element={<SignIn />} />
<Route path="/signup" element={<SignUp />} />
</Route>
<Route element={<PrivateRoute />}>
<Route path="/profile" element={<Profile />} />
<Route path="/testpage" element={<TestPage />} />
<Route path="/testresult" element={<TestResultPage />} />
</Route>
</Route>
</Routes>
</Router>
);
};
■ 느낀점
하루종일 인증/인가 부분을 코드로 구현하는 게 어려워서 강의와 강의자료를 엄청 많이 봤다. 어떻게든 따라서 구현은했는데,, 아직 익숙하진 않은 것 같다. 좀 더 연습해야 할 것 같고, 내일은 테스트페이지와 테스트 결과 페이지를 구현하고 Tailwind CSS 도 해보기!
'TIL' 카테고리의 다른 글
개인과제 - MBTI 성격 유형 테스트 ③ (2) | 2024.09.11 |
---|---|
개인과제 - MBTI 성격 유형 테스트 ② (0) | 2024.09.10 |
Axios, TanStack Query, Zustand, 인증/인가 (1) | 2024.09.06 |
git pull 동기화 전략 (0) | 2024.09.05 |
뉴스피드 팀 프로젝트 ⑤ - 마무리, 회고 (1) | 2024.09.04 |