Skip to content

FE 로그인 기능 구현

진예원 edited this page Dec 3, 2024 · 1 revision

처음 생각한 구현 방법

  1. 리다이렉트 : 카카오 로그인을 누르면 카카오 로그인 페이지로 이동한다.
  2. 토큰 전달 방법 : 사용자가 로그인에 성공을 하면, Callback URL에 accessToken과 refreshToken이 담기고 리다이렉트 된다.
  3. 토큰 보관 방법 accessToken은 zustand에 보관을 한다. refreshToken은 쿠키에 저장한다.

❓ 리다이렉트

“카카오 로그인을 누르면 카카오 로그인 페이지로 이동한다.”

이를 위해 Button 태그에 onClick 이벤트 핸들러가 호출되면 GET /api/auth/naver 와 같은 fetch 요청을 보냈다. 하지만 여기서 아래와 같은 CORS 에러 발생했다.

<button onClick={() => fetch("/api/auth/kakao")}>
  <img className="w-4" src={KakaoLogo}></img>
  카카오 로그인
</button>

CORS PNG

OAuth 인증의 핵심 과정은 리다이렉션인데, 이 과정은 브라우저가 사용자에게 인증을 요청하고, 인증이 완료된 후 다시 리다이렉트된 URL에서 토큰을 처리하는 방식이기 때문에 비동기 요청(fetch)으로 처리할 수 없는 것이었다.

그래서 a태그의 href를 이용하여 해결했다.

<a href="/api/auth/kakao">
  <img className="w-4" src={KakaoLogo}></img>
  카카오 로그인
</a>
Recording.30.mp4



❓ 토큰 전달 방법 + 토큰 보관 방법

방법 1 : URL 파라미터로 전달

서버에서 URL 파라미터에 accessTokenrefreshToken을 담아서 메인 경로 /로 리다이렉트

장점 : 간편하게 accessToken을 인메모리에 저장 가능

단점 : 보안상 좋지 않다. (RFC 문서에 URL 파라미터로 절대 토큰을 넘기지 말라고 나와있다!)


방법 2 : HttpOnly 쿠키로 전달

서버에서 HttpOnly 옵션으로 accessTokenrefreshToken 을 쿠키에 담아 메인 경로 /로 리다이렉트한다.

장점 : 매우 안전하다. (XSS 공격 방지)

단점 : 클라이언트에서는 token에 접근할 수 없다.

  • HttpOnly 쿠키는 자바스크립트의 Document.cookie API에서 접근할 수 없다.
  • 로그인 상태, 토큰 만료 여부를 알 수 없다.

방법 3. response body에 전달

서버에서 accessToken 을 response body에 담아 클라이언트로 전달한다.

장점 : 클라이언트에서 AccessToken을 직접 다룰 수 있다.

단점 : XSS 공격에 취약하다.



✅ 선택한 방법 : HttpOnly 쿠키로 전달

서버에서 HttpOnly 옵션으로 accessTokenrefreshToken 을 쿠키에 담아 메인 경로 /로 리다이렉트하기로 했다.

이 방법을 선택한 이유는 클라이언트에서 accessToken에 접근할 상황이 많이 없고, 안전하기 때문이었다.

res.cookie('accessToken', accessToken, { httpOnly: true, maxAge: HOUR });
res.cookie('refreshToken', refreshToken, {
  httpOnly: true,
  maxAge: WEEK,
});



✅ Tanstack query를 이용한 로그인 상태 관리

원래는 accessToken을 전역 상태로 관리하려고 했다.

accessToken을 전역 상태로 관리하기 위해서는 토큰을 URL Parameter이나 response body로 전달받아 직접 클라이언트에 보관해야한다. 하지만 이는 보안상 문제가 있다고 판단돼서, 토큰을 HttpOnly 옵션의 쿠키로 전달 받았다. (HttpOnly 옵션의 쿠키는 클라이언트에서 자바스크립트 코드로 참조할 수 없다!!)

HttpOnly 쿠키로 전달 받은 토큰을 클라이언트에서 관리할 수 없고, 로그인 상태도 결국 서버 상태에 가깝다고 생각해서 Tanstack Query로 관리하기로 했다.

개발 문서

⚓️ 사용자 피드백과 버그 기록
👷🏻 기술적 도전
📖 위키와 학습정리
🚧 트러블슈팅

팀 문화

🧸 팀원 소개
⛺️ 그라운드 룰
🍞 커밋 컨벤션
🧈 이슈, PR 컨벤션
🥞 브랜치 전략

그룹 기록

📢 발표 자료
🌤️ 데일리 스크럼
📑 회의록
🏖️ 그룹 회고
🚸 멘토링 일지
Clone this wiki locally