Spring
Spring OAuth2 소셜 로그인 — Google, Kakao, Naver 연동까지
OAuth2 Authorization Code Grant 흐름부터 Spring Security OAuth2 Client 설정, CustomOAuth2UserService 구현, 회원가입/로그인 분기 처리까지 인터랙티브 시각화로 완전 정복합니다.
2026-03-22 · 약 13분 읽기
Q. "Spring Boot에서 OAuth2 소셜 로그인을 구현하는 방법을 설명하고, Google·Kakao·Naver를 연동할 때 플랫폼별 차이점은 무엇인지 말씀해주세요."
예상 꼬리질문
답변 가이드
OAuth2 소셜 로그인은 사용자가 자격증명을 직접 제공하지 않고, Google·Kakao·Naver 같은 외부 서비스에 인증을 위임하는 방식입니다. Spring Boot에서는 spring-boot-starter-oauth2-client 의존성 하나로 복잡한 OAuth2 흐름 대부분이 자동 처리됩니다.
핵심 흐름은 Authorization Code Grant 방식으로, 사용자가 소셜 플랫폼에서 인증 후 받은 인가 코드(Authorization Code)를 서버가 백채널(back-channel)로 Access Token과 교환합니다. 이 방식은 Access Token이 브라우저에 직접 노출되지 않아 보안에 유리합니다.CustomOAuth2UserService를 구현하여 각 플랫폼의 응답 구조 차이를OAuthAttributes라는 통합 객체로 변환하고,provider + providerId 조합으로 사용자를 식별하여 회원가입과 로그인을 분기합니다.
실무에서는 Google은 CommonOAuth2Provider로 자동 설정되지만, Kakao와 Naver는 Spring Security 기본 제공 Provider가 없어 application.yml에 authorization-uri, token-uri, user-info-uri를 직접 정의해야 합니다. 특히 Naver는 응답 구조가 response 키 하위에 중첩되어 있어 OAuthAttributes 파싱 로직에서 별도 처리가 필요합니다.
"Google로 로그인" 버튼 하나가 어떻게 동작하는지 정확히 설명할 수 있나요? 면접관이 이 질문을 할 때 원하는 건 단순 구현 방법이 아니라OAuth2 프로토콜의 보안 설계 의도를 이해하고 있는지입니다. 이 아티클에서는 8단계 Authorization Code 흐름을 인터랙티브 시뮬레이션으로 체험하고, Spring Security가 이 흐름을 어떻게 추상화하는지 코드 레벨까지 살펴봅니다.
1. OAuth2 Authorization Code Grant 흐름
꼬리질문: "Authorization Code Grant 흐름을 단계별로 설명해주세요."
소셜 로그인의 핵심은 인가 코드(Authorization Code) 방식입니다. 사용자가 소셜 플랫폼에서 직접 인증하고, 우리 서버는 인가 코드를 받아백채널(브라우저가 아닌 서버 간 통신)로 Access Token을 교환합니다. Access Token이 브라우저에 노출되지 않는다는 점이 핵심 보안 장치입니다.
흐름은 총 8단계로, Spring Security OAuth2 Client가 3~6단계를 자동으로 처리합니다. 개발자가 직접 구현해야 하는 부분은 7단계(사용자 정보 파싱)와 8단계(회원가입/로그인 분기)입니다.
브라우저
(사용자)
우리 서버
(Spring Client)
소셜 플랫폼
(Auth Server)
사용자 정보 서버
(Resource Server)
사용자가 "Google로 로그인" 버튼 클릭
GET /oauth2/authorize?response_type=code&client_id=xxx&redirect_uri=xxx&scope=email,profile&state=난수2. Spring Security OAuth2 Client 설정 — Google vs Kakao vs Naver
꼬리질문: "Google, Kakao, Naver 연동 설정에서 차이점은 무엇인가요?"
세 플랫폼 연동의 설정 복잡도가 다릅니다.Google은 Spring Boot가 자동으로 Provider 정보를 알고 있어client-id와 client-secret만 설정하면 됩니다. 반면 Kakao와 Naver는 CommonOAuth2Provider에 포함되지 않아 authorization-uri, token-uri, user-info-uri를 모두 직접 정의해야 합니다.
Naver는 추가로 user-name-attribute: response를 설정해야 합니다. Naver의 API 응답이 응답 객체 하위에 중첩되어 있어, Spring Security가 사용자 식별 키로 response 객체를 사용하도록 지정해야 합니다.
Google OAuth2 설정
CommonOAuth2Provider 내장 — provider 섹션 불필요
자동 설정 (설정 불필요)
직접 설정 필요
3. CustomOAuth2UserService와 OAuthAttributes 구현
꼬리질문: "각 소셜 플랫폼의 사용자 정보를 어떻게 통합 처리하나요?"
세 플랫폼의 사용자 정보 응답 구조가 모두 다릅니다. Google은 최상위 레벨에 name, email, picture가 있고, Kakao는 kakao_account.profile.nickname 구조로 2단계 중첩, Naver는 response.name 구조로 1단계 중첩입니다. 이 차이를 흡수하는 것이 OAuthAttributes 값 객체입니다.
JSON 필드에 마우스를 올리면 OAuthAttributes 매핑 대상이 하이라이트됩니다.
OAuthAttributes.ofGoogle()최상위 레벨에서 직접 파싱 — 가장 단순한 구조API 응답 구조
OAuthAttributes 매핑
attributes["sub"].providerIdattributes["name"].nameattributes["email"].emailattributes["picture"].picture중첩 깊이
JSON 필드에 마우스를 올리면 매핑 대상이 하이라이트됩니다
4. 회원가입/로그인 분기 — provider + providerId 식별 전략
꼬리질문: "email이 아닌 provider+providerId로 식별하는 이유는 무엇인가요?"
saveOrUpdate()의 핵심은 email이 아닌 provider + providerId 조합으로 사용자를 식별한다는 점입니다. email을 주 식별자로 쓰면 두 가지 문제가 생깁니다. 같은 이메일로 Google과 Kakao에 각각 가입한 경우 동일인으로 잘못 처리될 수 있고, Kakao처럼 이메일 제공이 선택사항인 플랫폼에서는 email이 null일 수 있습니다.
시나리오 버튼을 클릭하여 신규 가입과 기존 로그인 흐름을 비교해보세요.
loadUser() 호출
OAuth2UserService.loadUser()
registrationId 판별
"google" / "kakao" / "naver"
OAuthAttributes.of()
플랫폼별 파서로 통합 객체 생성
DB 조회
provider+providerId
회원가입
toEntity() — Role.USER 부여
로그인 처리
update() — 이름·사진 최신화
userRepository.save()
신규/업데이트 모두 저장
DefaultOAuth2User 반환
GrantedAuthority 포함
JWT 발급 + Redirect
OAuth2SuccessHandler
코드 상세
노드에 마우스를 올리면
코드 예시가 표시됩니다
자주 발생하는 문제
실무에서 자주 마주치는 소셜 로그인 트러블슈팅 3가지
마무리
- - Authorization Code Grant: Access Token이 브라우저에 노출되지 않는 안전한 흐름. State 파라미터로 CSRF 방어
- - Google: CommonOAuth2Provider 자동 설정, Kakao·Naver: provider 섹션에 URI 직접 정의 필요
- - OAuthAttributes: 플랫폼별 응답 구조 차이를 통합 처리, provider + providerId로 사용자 식별
- - 소셜 로그인 성공 후 OAuth2SuccessHandler에서 JWT를 발급하여 Stateless 인증 구현
- - 더 알아볼 주제: OAuth2 PKCE 확장, OpenID Connect(OIDC)와 OAuth2의 차이, 소셜 계정 연동(계정 머징), Refresh Token 자동 갱신 전략
이해도 체크 퀴즈
OAuth2 소셜 로그인 핵심 개념을 코드와 시나리오로 확인해보세요.
Authorization Code 전달 경로
// "Google로 로그인" 버튼 클릭 후 OAuth2 흐름 진행 중 // Authorization Code는 어떤 경로로 전달되나요? // 선택지를 읽고 올바른 흐름을 고르세요.
소셜 로그인 사용자 식별 전략
// 홍길동 씨는 동일한 이메일(hong@example.com)로 // Google과 Kakao 계정을 모두 사용합니다. // 소셜 로그인 구현 시 사용자 식별 전략으로 올바른 것은?
Naver API 응답에서 이메일 추출
// Naver 로그인 후 다음 응답을 받았습니다.
// Map<String, Object> attributes 로 주입된 상태입니다.
{
"resultcode": "00",
"message": "success",
"response": {
"id": "abc123",
"name": "홍길동",
"email": "hong@naver.com"
}
}
// ofNaver()에서 이메일을 올바르게 추출하는 코드는?Kakao client-authentication-method 설정 이유
# application.yml — Kakao 설정
kakao:
client-id: ${KAKAO_CLIENT_ID}
client-secret: ${KAKAO_CLIENT_SECRET}
client-authentication-method: client_secret_post
authorization-grant-type: authorization_code
// client-authentication-method: client_secret_post 를
// 설정하는 이유는?OAuth2 State 파라미터가 방어하는 공격
// OAuth2 인가 요청 시 state 파라미터에 난수를 생성하여 전송 GET /oauth2/authorize? response_type=code &client_id=xxx &redirect_uri=xxx &state=랜덤_난수_값 // ← 이 파라미터의 역할은? // 콜백에서 동일한 state 값이 돌아오는지 검증합니다. // 이 메커니즘이 방어하는 공격 유형은?
추가 학습 자료를 공유합니다.
- 기억보단 기록을 — 스프링 시큐리티와 OAuth 2.0으로 로그인 기능 구현하기 — 국내에서 가장 많이 참조되는 Spring Boot OAuth2 구현 가이드. 이동욱님 작성, 코드 예제가 실용적이고 이해하기 쉬움
- Kakao 개발자 문서 — 카카오 로그인 — Kakao OAuth2 API 공식 레퍼런스. 동의항목 설정과 응답 구조 확인 필수
- Naver 개발자 문서 — 네이버 로그인 — Naver OAuth2 API 공식 레퍼런스. Callback URL 등록 방법 포함
의견을 들려주세요
서비스 개선에 큰 도움이 됩니다. 익명으로 자유롭게 남겨주세요.