Skip to content

[5주차/카사] 워크북 제출합니다.#55

Open
jjeunv wants to merge 2 commits intoUMC-Inha:카사/mainfrom
jjeunv:main
Open

[5주차/카사] 워크북 제출합니다.#55
jjeunv wants to merge 2 commits intoUMC-Inha:카사/mainfrom
jjeunv:main

Conversation

@jjeunv
Copy link
Copy Markdown

@jjeunv jjeunv commented May 3, 2026

✅ 워크북 체크리스트

  • 모든 핵심 키워드 정리를 마쳤나요?
  • 핵심 키워드에 대해 완벽히 이해하셨나요?
  • 이론 학습 이후 직접 실습을 해보는 시간을 가졌나요?
  • 미션을 수행하셨나요?
  • 미션을 기록하셨나요?

✅ 컨벤션 체크리스트

  • 디렉토리 구조 컨벤션을 잘 지켰나요?
  • pr 제목을 컨벤션에 맞게 작성하였나요?
  • pr에 해당되는 이슈를 연결하였나요?(중요)
  • 적절한 라벨을 설정하였나요?
  • 파트장에게 code review를 요청하기 위해 reviewer를 등록하였나요?
  • 닉네임/main 브랜치의 최신 상태를 반영하고 있는지 확인했나요?(매우 중요!)

📌 주안점

export default function ProtectedRoute() {
const { accessToken } = useAuth();

if (!accessToken) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게도 할 수 있군요! 항상 꼼꼼하게 주석 달아주셔서 코드 보는게 너무 편합니다!

});

// 여러 요청이 동시에 401을 받았을 때 단 한 번의 refresh만 실행되도록 단일 인스턴스로 공유해야 하기 때문에 전역 상태로 관리
let isRefreshing = false;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

각 요청이 독립적으로 refresh를 시도하면서 /auth/refresh가 여러 번 호출되게 되는데,
isRefreshing 플래그로 refresh를 한 번만 실행하고 나머지 요청은 refreshSubscibers에 쌓아뒀다가 일괄 재시도하는 구조는 refresh 요청을 서버로 1번만 보내므로 효율적인 것 같습니다! 👍🏻

Copy link
Copy Markdown
Collaborator

@qkrdmsthff qkrdmsthff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 카사 !! 이번에두 많은 고민을 하시고 코드를 작성하신 게 너무 보이고 멋지네요 저보다 잘 짜시는 것 같아요 코드를 ㅎㅎ,,, 수고하셨고 이번주도 화이팅입니다!

Comment on lines +27 to +29
// null로 설정하면 ProtectedRoute가 리렌더링되어 /login으로 자동 리다이렉트
setAccessToken(null);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로그인 실패 시 로그인 화면으로 리렌더링 하는 로직 너무 좋습니다! 이거 놓치신 분들 몇 분 계셨는데 아주 마음에 드네용 ㅎㅎ

Comment on lines +16 to +29
function login(newAccessToken: string, newRefreshToken: string) {
// localStorage: 새로고침 후에도 로그인 상태 유지
// state: 컴포넌트 리렌더링 트리거 (ProtectedRoute가 즉시 반응)
localStorage.setItem("accessToken", newAccessToken);
localStorage.setItem("refreshToken", newRefreshToken);
setAccessToken(newAccessToken);
}

function logout() {
localStorage.removeItem("accessToken");
localStorage.removeItem("refreshToken");
// null로 설정하면 ProtectedRoute가 리렌더링되어 /login으로 자동 리다이렉트
setAccessToken(null);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 login 과 logout 함수는 AuthProvider 가 리렌더링될 때마다 새로운 참조값으로 재생성됩니다!

이 Context 를 구독하는 하위 컴포넌트들이 useEffect 의 의존성 배열에 login / logout 을 넣을 경우, 의도치 않은 무한 루프나 불필요한 effect 를 실행시킬 수 있습니다!

useCallback 으로 감싸서 함수의 참조를 고정해 보면 좋을 것 같아용!


// 로그인·회원가입·refresh 엔드포인트에서 발생한 401은 토큰 만료가 아닌 자격증명 오류이므로 refresh를 시도하면 안 됨
// (특히 /auth/refresh가 없으면 무한 루프 발생)
const AUTH_ENDPOINTS = ["/auth/signin", "/auth/signup", "/auth/refresh"];
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AUTH_ENDPOINTS 처럼 고정된 경로들을 코드 내부에 두는 것도 좋지만, 프로젝트 규모가 커진다면 별도의 constants/api.ts 파일로 분리하여 관리하는 것이 좋습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chapter05_리프레시 토큰 기반의 안전한 접근 제어 전략과 소셜 로그인

4 participants