[table-now] Spring Security의 oauth2Login() 대신 WebClient를 선택한 이유

2025. 5. 28. 23:06·Dev Projects

🔍 개요

이전에 작성했던 글

- 2025.03.21 - [Java Study/Frameworks] - Spring Security를 활용한 JWT 인증 | Stateless하게 제대로 적용하기!

- 2025.04.21 - [Dev Projects] - [table-now] 소셜 로그인(Kakao, Naver) 통합 구현기

에서는 JWT 기반 인증 구조에서 Stateless 특성이 왜 중요한지와 해당 특성을 살리면서 개발하는 방법에 대해 설명했습니다.

 

`table-now` 프로젝트에서는 기본적으로 Spring Security + JWT 기반 인증 구조를 먼저 설계하고 구현해두었습니다.  
역할 기반 인가 처리는 `@Secured` 어노테이션을 통해 명확하게 적용하고, 인증 정보는 `SecurityContextHolder`(`@AuthenticationPrincipal`)를 통해 주입 및 관리했습니다.

이후 소셜 로그인(Kakao, Naver)을 추가하면서도 기존 구조의 Stateless 특성과 인증 흐름의 일관성을 유지하기 위해,  
Spring Security의 기본 OAuth2 방식 대신 WebClient를 이용한 직접 구현 방식을 선택하게 되었습니다.

 

이번 글에서는 `table-now` 프로젝트에서 WebClient를 사용해 소셜 로그인을 구현한 이유를 Spring Security의 기본 방식(`oauth2Login`)과 비교하여 정리해보았습니다.

 


⚙️ WebClient 기반 소셜 로그인 설계 배경

1. Spring Security의 oauth2Login() 방식의 한계

Spring Security에서 제공하는 `oauth2Login()`은 다음과 같은 구조를 따릅니다:

  1. 사용자가 `/oauth2/authorization/{provider}`로 진입
  2. 스프링 시큐리티가 자동으로 인가 코드 → 액세스 토큰 → 사용자 정보까지 처리
  3. `OAuth2UserService`를 통해 사용자 정보를 가져옴
  4. `HttpSession`을 이용해 사용자 인증 상태를 유지

이 방식은 결국 세션 기반 인증이며, JWT의 Stateless 구조와 충돌하게 됩니다.

 

2. WebClient로 직접 구현한 이유

WebClient를 통해 OAuth2 인증 과정을 직접 구현하면 다음과 같은 장점이 있습니다:

✅ 장점

  • Stateless 구조 유지
        인증 정보를 세션에 저장하지 않고, JWT 발급을 통해 관리
  • 일반 로그인/소셜 로그인 흐름 통일
        일한 방식으로 JWT를 발급하고 처리 → 인증 구조 단순화
  • 유연한 커스터마이징
        액세스 토큰 요청, 사용자 정보 파싱, 예외 처리 등을 직접 제어 가능

 

3. 실제 구현 흐름

출처: [10분 테코톡] 홍실의 OAuth 2.0 (https://youtu.be/Mh3LaHmA21I?si=7Hl37OxNH4DNEuqG)

/oauth2/authorization/kakao 
→ 인가 코드 수신 
→ WebClient로 액세스 토큰 요청
→ 사용자 정보 요청 
→ 유저 존재 여부 판단 및 최초 로그인 시 자동 가입
→ JWT 발급
→ 응답 반환 및 SecurityContextHolder 저장

이 흐름은 일반 로그인과 동일한 방식으로 JWT를 발급되므로
모든 인증 방식이 일관된 방식으로 통합됩니다.

 


📝 회고

Spring Security는 기본적으로 세션 기반 인증을 전제로 설계되어 있습니다.
JWT의 Stateless 구조와 함께 사용하기 위해서는 많은 고민과 선택이 필요했습니다.

이번 소셜 로그인 구현은 그 고민의 결과물로, WebClient를 선택함으로써 

- Stateless 구조 유지와
- 일반 로그인/소셜 로그인 간 인증 로직의 일관성 확보

라는 두 가지 목표를 모두 달성할 수 있었습니다.

 

⬇️ 구현 결과와 개선은 아래 Github 링크에서 확인할 수 있습니다.

더보기

https://github.com/spring-team-7/table-now/pull/40

 

[feat] 소셜 로그인 기능 구현 by mannaKim · Pull Request #40 · spring-team-7/table-now

🔗 Issue Number close #11 📝 작업 내역 카카오 로그인 API 구현 네이버 로그인API 구현 💡 PR 특이사항 로그인 요청 흐름 클라이언트가 로그인 버튼 클릭 소셜 로그인 동의 화면으로 리다이렉트 카카

github.com

: 최초 구현 코드 PR

 

https://github.com/spring-team-7/table-now/pull/43

 

[refactor] 소셜 로그인 기능 개선 by mannaKim · Pull Request #43 · spring-team-7/table-now

🔗 Issue Number close #41 📝 작업 내역 getKakaoUserInfo와 getNaverUserInfo 메서드의 반환값을 Map → DTO 객체로 변경 패키지 구조 리팩토링 💡 PR 특이사항

github.com

: 개선 코드 PR

 

https://github.com/spring-team-7/table-now

 

GitHub - spring-team-7/table-now: 🍽️ Table-Now : 식당을 예약하고 방문할 수 있는 실시간 예약 관리 시스

🍽️ Table-Now : 식당을 예약하고 방문할 수 있는 실시간 예약 관리 시스템. Contribute to spring-team-7/table-now development by creating an account on GitHub.

github.com

: 전체 프로젝트 (최종 코드 참고)

 

저작자표시 비영리 변경금지 (새창열림)

'Dev Projects' 카테고리의 다른 글

[table-now] 1:1(예약자:가게) 채팅 기능 고도화를 위해 RabbitMQ Relay를 적용한 이유  (0) 2025.06.05
[table-now] 예약자-사장님 1:1 실시간 채팅 기능 설계 및 구현  (2) 2025.06.04
[table-now] 의사결정 기록 - 외부 연동 시스템 예외 처리 강화 리팩토링  (0) 2025.05.23
[table-now] S3 이미지 업로드 - Presigned Url 방식으로 구현하기  (1) 2025.05.23
[table-now] AccessToken 블랙리스트 기반 토큰 무효화 기능 구현  (0) 2025.04.22
'Dev Projects' 카테고리의 다른 글
  • [table-now] 1:1(예약자:가게) 채팅 기능 고도화를 위해 RabbitMQ Relay를 적용한 이유
  • [table-now] 예약자-사장님 1:1 실시간 채팅 기능 설계 및 구현
  • [table-now] 의사결정 기록 - 외부 연동 시스템 예외 처리 강화 리팩토링
  • [table-now] S3 이미지 업로드 - Presigned Url 방식으로 구현하기
기만나🐸
기만나🐸
공부한 내용을 기록합시다 🔥🔥🔥
  • 기만나🐸
    기만나의 공부 기록 🤓
    기만나🐸
  • 전체
    오늘
    어제
    • ALL (143)
      • TIL (Today I Learned) (53)
      • Dev Projects (14)
      • Algorithm Solving (67)
        • Java (52)
        • SQL (15)
      • Certifications (8)
        • 정보처리기사 실기 (8)
  • 인기 글

  • 태그

    BOJ
    Subquery
    DFS
    BFS
    HTML
    그리디
    Firebase
    java
    GROUP BY
    백트래킹
    Google Fonts
    프로그래머스
    mysql
    백준
    시뮬레이션
    jQuery
    다이나믹프로그래밍
    join
    sql
    websocket
    dp
    자료구조
    programmers
    javascript
    bootstrap
    CSS
    완전탐색
    greedy
    jpa
    jwt
  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
기만나🐸
[table-now] Spring Security의 oauth2Login() 대신 WebClient를 선택한 이유
상단으로

티스토리툴바