✅ 카카오 소셜 로그인 전체 흐름 정리
(프론트, 카카오, 백엔드, DB, 브라우저 사이 데이터 흐름 중심)
### 🔐 전제 세팅 정보
• 프론트 주소: http://localhost:3000
• 백엔드 주소: http://localhost:8080
• 카카오 로그인 Redirect URI: http://localhost:8080/login/oauth2/code/kakao
• 프론트 최종 리디렉트 URI: http://localhost:3000/oauth/callback
💡 카카오 소셜 로그인 상세 흐름
✅ 1. 프론트: 로그인 버튼 클릭
// React 등 프론트 코드
window.location.href = "http://localhost:8080/oauth2/authorization/kakao";
• 의도: 소셜 로그인 시작 요청
✅ 2. 프론트 → 백엔드: 소셜 로그인 요청
GET /oauth2/authorization/kakao
• 의도: Spring Security가 자동으로 카카오 인증 서버로 리다이렉트 처리
✅ 3. 백엔드 → 카카오 서버: 인가 요청
GET https://kauth.kakao.com/oauth/authorize?client_id=abc123&redirect_uri=http://localhost:8080/login/oauth2/code/kakao&response_type=code&scope=profile_nickname,account_email
• 요청 데이터:
• client_id: 카카오 앱의 REST API 키
• redirect_uri: 인증 성공 후 돌아올 백엔드 주소
• response_type=code: 인가 코드를 요청
• scope: 이메일, 닉네임 접근 요청
✅ 4. 사용자: 카카오 로그인 진행 (카카오 서버)
• 사용자가 카카오 로그인 UI에서 로그인 및 정보 동의
• 로그인 완료 시, 카카오가 백엔드로 인가 코드(code) 전달
✅ 5. 카카오 서버 → 백엔드 리다이렉트
GET /login/oauth2/code/kakao?code=xyz456
• 전송 데이터:
• code=xyz456: 카카오 인가 코드
✅ 6. 백엔드 → 카카오: 액세스 토큰 요청
POST https://kauth.kakao.com/oauth/token
Content-Type: application/x-www-form-urlencoded
client_id=abc123
client_secret=secret456
grant_type=authorization_code
code=xyz456
redirect_uri=http://localhost:8080/login/oauth2/code/kakao
• 요청 목적: 인가 코드를 통해 카카오 AccessToken을 발급받기
✅ 7. 카카오 → 백엔드: 액세스 토큰 응답
{
"access_token": "kakao_access_token_value",
"token_type": "bearer",
"refresh_token": "kakao_refresh_token_value",
"expires_in": 21599,
"scope": "account_email profile_nickname"
}
✅ 8. 백엔드 → 카카오: 사용자 정보 요청
GET https://kapi.kakao.com/v2/user/me
Authorization: Bearer kakao_access_token_value
✅ 9. 카카오 → 백엔드: 사용자 정보 응답
{
"id": 1234567890,
"kakao_account": {
"email": "user@example.com",
"profile": {
"nickname": "홍길동"
}
}
}
✅ 10. 백엔드: 사용자 정보 파싱 및 확인
String email = "user@example.com";
String name = "홍길동";
String oauthId = "1234567890";
String provider = "kakao";
• OAuthRepository.existsByProviderAndOauthId()로 기존 회원인지 확인
• 기존 회원이면 → 로그인
• 신규 회원이면 → 리다이렉트로 회원가입 요청
✅ 11. 백엔드: 신규 유저일 경우
302 Redirect → http://localhost:3000/oauth/callback?provider=kakao&oauthId=1234567890&status=REGISTER
• 프론트가 회원가입 폼 띄우고 닉네임 같은 정보 추가 입력받아 /api/users/join 등으로 회원 생성 요청
✅ 12. 백엔드: 기존 유저일 경우 → JWT 발급
String accessToken = jwtUtil.createAccessToken(memberEmail, role);
String refreshToken = jwtUtil.createRefreshToken(memberEmail);
// refreshToken은 Redis 등에 저장해 유효성 관리 가능
✅ 13. 백엔드 → 프론트: 쿠키로 토큰 전달 + 리디렉트
Set-Cookie: access_token=...; HttpOnly; Secure; Path=/
Set-Cookie: refresh_token=...; HttpOnly; Secure; Path=/
Set-Cookie: role={"role":"MEMBER"}; Secure; Path=/
302 Redirect → http://localhost:3000/oauth/callback?status=SUCCESS
✅ 14. 프론트: 로그인 완료 처리
• /oauth/callback에서 로그인 성공 처리
• 쿠키는 자동 저장되어 브라우저에 보관됨
✅ 15. 이후 요청 시: 프론트 → 백엔드 API 요청
fetch("http://localhost:8080/api/users/me", {
method: "GET",
credentials: "include" // 쿠키 포함
});
• JwtAuthFilter가 access_token을 꺼내 사용자 인증
• 인증된 사용자만 API 사용 가능
✅ 16. AccessToken 만료 → Refresh 요청
fetch("http://localhost:8080/api/users/refresh", {
method: "POST",
credentials: "include"
});
• 서버가 refresh_token 쿠키 확인 후, 새로운 access_token 재발급
✅ 17. 데이터 저장 구조 요약
✅ member 테이블
필드설명
id | 고유 ID |
nickname | 닉네임 |
role | ENUM: ADMIN / MEMBER / BUSINESS |
✅ oauth 테이블
필드설명
id | 고유 ID |
provider | kakao |
oauthId | 1234567890 |
member_id | FK 연결된 member ID |
✅ 쿠키 구조 정리
이름값설명
access_token | JWT | 인증용 토큰 |
refresh_token | JWT | 재발급용 토큰 |
role | JSON 문자열 | 프론트 권한 판별용 |
✅ 전체 흐름 다이어그램 요약
[프론트]
↓ 클릭
/oauth2/authorization/kakao
↓
[백엔드] Spring Security 처리
→ 카카오 리다이렉트
↓
[카카오] 로그인 → 인가코드 발급
↓
[백엔드]
→ 카카오 토큰 요청
→ 사용자 정보 요청
→ member / oauth 확인 및 저장
→ JWT 생성
→ 쿠키에 저장
↓
[프론트]
→ 쿠키 자동 저장
→ API 요청 시 JWT 포함
✅ 보안 요약
• access_token: HttpOnly + Secure 쿠키 저장 → JS 접근 불가
• refresh_token: 재발급 전용 → Redis로 유효성 관리 가능
• 쿠키는 Path=/ 설정 → 전체 경로에서 자동 전송
✅ 마무리
이 전체 과정이 결국 다음 3가지 핵심 흐름으로 요약됩니다:
1. OAuth2 인증 및 사용자 정보 획득 (소셜 서버와 통신)
2. 백엔드에서 JWT 발급 및 쿠키 저장 (stateless 인증 전환)
3. 프론트에서 쿠키 기반 요청으로 인증 유지
출처 : ChatGPT
'BE > Spring & Spring Boot' 카테고리의 다른 글
[Spring Boot] 웹소켓 (1) | 2025.04.19 |
---|---|
[Spring Boot] @CacheEvict (0) | 2025.04.15 |
[Spring Boot] WebFlux (0) | 2025.04.01 |
[Spring Boot] DAO와 Repository의 차이? (1) | 2025.03.31 |
[Spring Boot] DAO (0) | 2025.03.30 |