heyday2024 님의 블로그
팀프로젝트 피드백 본문
https://mountain-due.vercel.app/
피드백 (제천 튜터님)
- 전반적으로 quality 가 매우 좋습니다
- 제출하실때 이미지 파일 용량이 매우 컸습니다, 하나당 79MB ㄷㄷ 이미지 파일을 최적화하는 것이 좋습니다. https://squoosh.app/ (Google에서 제공하는 이미지 최적화)
- 비로그인 시 좋아요을 disabled 하는 것이 아니라 회원가입/로그인을 유도하는 방식의 UX가 더 선호됩니다
- 실시간 유효성 검사와 제출버튼 로직을 매우 잘 짜셨습니다
- 현재 위치에 따른 지도 interaction이 좋습니다
- Google 소셜 로그인도 잘 되어있습니다만, 이용약관에 대한 유효성 검사를 적용시킬 수 있는 부분이 필요하다고 생각됩니다.
- 좋아요가 optimistic update가 잘 적용됩니다.
- 낙관적 업데이트일때 더보기 눌렀을때, 잠깐 로딩바가 나오는 식의 방식도 선호됩니다.
- 유튜브 페이지에서의 유튜브의 카드가 transform을 사용하셨는데 transition도 사용해주시면 좋을 것 같습니다.
- useUser라는 커스텀 훅의 필요 여부가 의심됩니다. 이미 상태관리가 되고 있는 듯한데, hook의 여부가 필요해보이지 않습니다.
- commit convention과 PR을 잘 관리하셨습니다.
- 이미지 파일 관리
- public / src의 의도에 따른 용도롤 구분하시는게 좋습니다.
- public을 검색 크롤링에 걸려 타인도 검색/사용이 가능한데 이 과정에서 웹페이지 서버 쪽에 불필요한 요청이 갈 수 있습니다.
<트러블 슈팅>
문제
- Google OAuth 후 세션 확인 및 사용자 정보 처리 누락
- OAuth 로그인 후 사용자의 인증 세션 정보가 제대로 확인되지 않아 로그인 상태를 유지하지 못함.
- redirectTo로 이동만 하고 사용자 데이터를 처리하지 않으면 앱 상태가 초기화된 상태로 표시됨.
- 사용자 경험(UX) 문제
- 로그인 성공 후 유저 정보를 Redux 상태에 저장하지 않으면 홈 화면에서 개인화된 데이터를 표시할 수 없음.
- 로그인 실패 시 적절한 에러 메시지와 경로로 리디렉션되지 않아 혼란을 초래.
- 보안 문제
- Google OAuth로 발급된 세션이 제대로 검증되지 않으면 악의적인 사용자가 인증 상태를 조작할 가능성이 있음.
==> GoogleCallback 컴포넌트(페이지)를 사용해서 세션 정보를 가져오면 해결할 수 있음.
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import { supabase } from "../../api/supabaseClient";
import { setUser } from "../../redux/slices/userSlice";
import useToastAlert from "../../hooks/useToastAlert";
const GoogleCallback = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
const showToast = useToastAlert();
useEffect(() => {
const fetchUserDetails = async () => {
try {
// 세션 정보 가져오기
const { data: sessionData, error: sessionError } =
await supabase.auth.getSession();
if (sessionError) {
console.error("세션 가져오기 실패:", sessionError.message);
showToast("로그인 처리 중 오류가 발생했습니다.", "error");
navigate("/login");
return;
}
const user = sessionData?.session?.user;
if (!user) {
console.error("Google OAuth 사용자 정보가 없습니다.");
showToast("로그인 실패: 사용자 정보를 가져올 수 없습니다.", "error");
navigate("/login");
return;
}
// `users` 테이블에서 사용자 정보 가져오기
const { data: userDetails, error: userError } = await supabase
.from("users")
.select("id, nickname, img_url")
.eq("id", user.id)
.single();
if (userError) {
console.error("users 테이블 조회 실패:", userError.message);
showToast("사용자 정보 조회 중 오류가 발생했습니다.", "error");
navigate("/signup?signup=false");
return;
}
// Redux 상태에 사용자 정보 저장
dispatch(setUser(userDetails));
showToast("로그인에 성공했습니다!", "success");
navigate("/");
} catch (err) {
console.error("로그인 처리 중 오류:", err.message);
showToast("로그인 처리 중 오류가 발생했습니다.", "error");
navigate("/login");
}
};
fetchUserDetails();
}, [dispatch, navigate, showToast]);
return <div>Google 로그인 처리 중...</div>;
};
export default GoogleCallback;
GoogleCallback 컴포넌트로 해결된 문제
- 세션 확인 및 로그인 상태 유지
- supabase.auth.getSession()을 통해 OAuth 인증 이후의 세션 정보를 가져옴.
- 세션 정보가 없을 경우 로그인 페이지로 리디렉션하여 무효한 세션 방지.
- 사용자 정보 Redux 상태 관리
- users 테이블에서 사용자 정보를 조회하고 Redux에 저장하여 개인화된 콘텐츠 제공.
- 유저가 로그인한 상태를 유지하며, 홈 화면에서 적절한 정보를 렌더링.
- 회원가입 상태 처리
- users 테이블에 정보가 없는 사용자는 추가 정보 입력 페이지(/signup)로 리디렉션.
- 기존 사용자는 바로 홈 화면으로 이동.
- 오류 처리 개선
- 세션 정보 조회 실패, 사용자 정보 조회 실패 등의 상황에 대한 적절한 알림과 대체 경로 제공.
- 예: 로그인 실패 시 사용자에게 "사용자 정보를 가져올 수 없습니다."라는 메시지와 함께 /login으로 리디렉션.
- UX 개선
- OAuth 이후의 인증 상태가 명확히 관리되며, 사용자는 혼란 없이 다음 화면으로 이동.
- 성공적인 로그인과 함께 알림을 통해 피드백 제공.
<느낀점/ 아쉬운 점>
- 이미지 파일이 차지하는 용량이 너무 커서 코드 폴더를 업로드 하는 과정이 오래걸렸다. 렌더링 시 인터넷 속도가 느리면, 확실히 이미지가 로드되는 과정에 많은 시간이 소요되었다. 앞으로 진행될 프로젝트에서는 이 부분을 항상 고려하여 이미지 용량을 줄여 써야겠다.
- 구글 소셜 로그인 부분에서 회원가입 창에는 차라리 구글 간편로그인 버튼을 없애고, 로그인 페이지에만 구글 간편 로그인 버튼을 보이게 했으면 더 좋았을 것 같다. 이것이 통상적으로 사용하는 방법이기도 하고, 사용자들이 비회원일 때 회원만 접근할 수 있는 페이지나 요소를 접근 시 로그인 페이지를 미리 보이게함으로 구글 간편 로그인을 쉽게 이용할 수 있개 했으면 좋았을 것 같다. 이런식으로 사용자에게 로그인 유도를 하는 것이 중요한 것 같다.
- 또한, 계정이 users테이블에 없어도 구글 간편 로그인 기능으로 알아서 자동으로 회원가입, 로그인을 한번에 하는 하게하는 것이 사용자 경험에서도 더 좋을 것 같다. 이번에 UX를 제대로 고려하지 못하고, sign up, login 페이지에서 구글 소셜 로그인과 구글 소셜 회원가입 이렇게 기능을 굳이 커스터마이징해서 쪼개 사용했는데, 이렇게 진행하지 않았더라면 더욱 빠르게 기능을 구현할 수 있었을 것 같아 아쉬웠다. 앞으로는 개발을 할 때 필요로하는 기능만 고려하는 것이 아니라 사용자의 경험, 즉, UX를 항상 고려하면서 어떻게 웹 사이트를 더욱 좋은 방향으로 개선시킬 수 있을지 신중히 생각하면서 코드를 짜야겠다. 또한 최적화를 위해 리렌더링을 최소화하는 것, 그리고 재사용될 수 있는 코드는 최대한 컴포넌트화하여 손쉽게 다른 개발자들도 그 컴포넌트를 잘 사용할 수 있게 구조를 짜는 것이 협업 시 더욱 중요하다고 생각하고 이 부분을 다음 프로젝트 진행 시 잘 해낼 수 있게 연습을 해봐야겠다.
'프론트엔드 부트캠프' 카테고리의 다른 글
[Typescript] 타입 스크립트 동작 원리, 타입 추론, 제네릭 (0) | 2024.12.21 |
---|---|
Next.js 렌더링 패턴과 구현 방식 (2) | 2024.12.10 |
유효성 검사와 supabase storage (0) | 2024.12.03 |
상태 관리 방법 비교 총정리 (0) | 2024.11.29 |
HTTP, HTTPS (2) | 2024.11.28 |