-
Notifications
You must be signed in to change notification settings - Fork 3
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.cookie
API에서 접근할 수 없다. - 로그인 상태, 토큰 만료 여부를 알 수 없다.
서버에서 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에 대해 간단히 알아보기
YJS 가이드 근데 이제 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)