-
Notifications
You must be signed in to change notification settings - Fork 5
FE 로그인 기능 구현
-
리다이렉트: 카카오 로그인을 누르면 카카오 로그인 페이지로 이동한다. -
토큰 전달 방법: 사용자가 로그인에 성공을 하면, Callback URL에 accessToken과 refreshToken이 담기고 리다이렉트 된다. -
토큰 보관 방법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>
OAuth 인증의 핵심 과정은 리다이렉션인데, 이 과정은 브라우저가 사용자에게 인증을 요청하고, 인증이 완료된 후 다시 리다이렉트된 URL에서 토큰을 처리하는 방식이기 때문에 비동기 요청(fetch)으로 처리할 수 없는 것이었다.
그래서 a태그의 href를 이용하여 해결했다.
<a href="/api/auth/kakao">
<img className="w-4" src={KakaoLogo}></img>
카카오 로그인
</a>Recording.30.mp4
서버에서 URL 파라미터에 accessToken과 refreshToken을 담아서 메인 경로 /로 리다이렉트
장점 : 간편하게 accessToken을 인메모리에 저장 가능
단점 : 보안상 좋지 않다. (RFC 문서에 URL 파라미터로 절대 토큰을 넘기지 말라고 나와있다!)
서버에서 HttpOnly 옵션으로 accessToken 과 refreshToken 을 쿠키에 담아 메인 경로 /로 리다이렉트한다.
장점 : 매우 안전하다. (XSS 공격 방지)
단점 : 클라이언트에서는 token에 접근할 수 없다.
- HttpOnly 쿠키는 자바스크립트의
Document.cookieAPI에서 접근할 수 없다. - 로그인 상태, 토큰 만료 여부를 알 수 없다.
서버에서 accessToken 을 response body에 담아 클라이언트로 전달한다.
장점 : 클라이언트에서 AccessToken을 직접 다룰 수 있다.
단점 : XSS 공격에 취약하다.
서버에서 HttpOnly 옵션으로 accessToken 과 refreshToken 을 쿠키에 담아 메인 경로 /로 리다이렉트하기로 했다.
이 방법을 선택한 이유는 클라이언트에서 accessToken에 접근할 상황이 많이 없고, 안전하기 때문이었다.
res.cookie('accessToken', accessToken, { httpOnly: true, maxAge: HOUR });
res.cookie('refreshToken', refreshToken, {
httpOnly: true,
maxAge: WEEK,
});원래는 accessToken을 전역 상태로 관리하려고 했다.
accessToken을 전역 상태로 관리하기 위해서는 토큰을 URL Parameter이나 response body로 전달받아 직접 클라이언트에 보관해야한다. 하지만 이는 보안상 문제가 있다고 판단돼서, 토큰을 HttpOnly 옵션의 쿠키로 전달 받았다.
(HttpOnly 옵션의 쿠키는 클라이언트에서 자바스크립트 코드로 참조할 수 없다!!)
HttpOnly 쿠키로 전달 받은 토큰을 클라이언트에서 관리할 수 없고, 로그인 상태도 결국 서버 상태에 가깝다고 생각해서 Tanstack Query로 관리하기로 했다.
⚓️ 사용자 피드백과 버그 기록
👷🏻 기술적 도전
📖 위키와 학습정리
✏️ 에디터
Novel이란?
Novel 스타일링 문제
에디터 저장 및 고려 사항들
📠 실시간 협업, 통신
Yorkie와 Novel editor 연동
YJS와 Websocket 그리고 React-Flow
YJS와 Socket.io
WebSocket과 Socket.io에 대해 간단히 알아보기
🏗️ 인프라와 CI/CD
NCloud CI CD 구축
BE 개발 스택과 기술적 고민
private key로 원격 서버 접근
nCloud 서버, VPC 만들고 설정
monorepo로 변경
⌛ 캐시, 최적화
rabbit mq 사용법
🔑 인증, 인가, 보안
passport로 oAuth 로그인 회원가입 구현
FE 로그인 기능 구현
JWT로 인증 인가 구현
JWT 쿠키로 사용하기
refresh token 보완하기
🧸 팀원 소개
⛺️ 그라운드 룰
🍞 커밋 컨벤션
🧈 이슈, PR 컨벤션
🥞 브랜치 전략
🌤️ 데일리 스크럼
📑 회의록
1️⃣ 1주차
킥오프(10/25)
2일차(10/29)
3일차(10/30)
4일차(10/31)
2️⃣ 2주차
8일차(11/04)
9일차(11/05)
11일차(11/07)
13일차(11/09)
3️⃣ 3주차
3주차 주간계획(11/11)
16일차(11/12)
18일차(11/14)
4️⃣ 4주차
4주차 주간계획(11/18)
23일차(11/19)
24일차(11/20)
25일차(11/21)
5️⃣ 5주차
5주차 주간계획(11/25)
29일차(11/25)
32일차(11/28)
34일차(11/30)
6️⃣ 6주차
6주차 주간계획(12/2)
37일차(12/3)