Spring OAuth AccessToken 제대로 추출하기

2025. 10. 19. 13:21·트러블슈팅

✅ 개요

사용자가 OAuth로 인증한 상태에서 로그아웃 요청을 받으면 서버에서 JWT 처리(만료 쿠키, 블랙리스트 처리 등) 외 추가적으로 OAuth에 토큰 삭제 요청 API를 사용하려고 할 때 발생한 문제와 해결방법을 기록하고자 합니다.

 

✅ 문제 상황

OAuth 토큰 삭제 요청 API는 반드시 삭제 대상 액세스 토큰(JWT 아님)을 전달해야 합니다. 그리고 토큰은 `OAuth2AuthorizedClientService`를 통해 얻을 수 있으며, 토큰을 얻기 위해 필요한 메서드는 `loadAuthorizedClient`로 두 개의 인자를 받습니다.

`clientRegistrationId`는 kakao, google같은 값으로 DB에 잘 저장했다면 어렵지 않게 얻을 수 있습니다. 그리고 `principalName`은 시큐리티 컨텍스트에 저장되어 있는 `Authentication`의 `Principal`을 사용하면 될 것이라 생각했지만 현재 프로젝트 인증 구조상 정확히 일치하는 `principalName`을 얻기 어려움이 있었습니다. (인증 구조는 설명이 길어질 것 같아서 생략)

 

✅ 원인 분석

스프링부트 자동 설정에 의해 `OAuth2AuthorizedClientService`의 구현체 중 하나인 `InMemoryOAuth2AuthorizedClientService`가 빈으로 등록됩니다. 

 

인터페이스 메서드는 다음과 같이 오버라이드 되어 있습니다.

 `saveAuthorizedClient()`를 어느 단계에서 어떻게 호출하는지 알면 도움이 될 것 같아 디버깅 해 본 결과, `OAuth2LoginAuthenticationFilter`에서 호출하는 것을 확인했습니다.

`this.authorizedClientRepository`이지만 내부적으로 `OAuth2AuthorizedClientService` 에게 위임합니다. 

 

다시 돌아와서, `saveAuthorizedClient()`에서 `principal.getName()`이 무엇을 호출하는지 따라가 보았습니다.

`UserDetails.getUsername()`을 호출하고 있습니다. 그리고 저의 프로젝트에서는 다음과 같이 REST와 OAuth 공통 인증 객체를 사용하고 있습니다.

즉 이 인증 객체에서 재정의하는 `getUsername()`의 반환값이 OAuth 액세스 토큰을 가져오는 데 중요한 역할을 한다는 것을 알았습니다. 이때 이메일이나 사용자 이름을 반환하는 방법이 있는데 이 정보들은 충분히 사용자에 의해 변경될 수 있는 값들이기 때문에 유지보수하기 어렵다고 판단했습니다. 그래서 고유하게 식별할 수 있는 무언가가 필요하다고 생각했습니다.

 

✅ 해결 방법

OAuth 인증 과정에서의 응답 중 `sub` 또는 `id`가 있습니다. 이 값은 식별자 역할을 하기 때문에 확실히 고유하여 사용하기에 적절할 것이라고 판단했습니다. 그래서 `getUsername()`에서는 `sub` 또는 `id`값을 반환하도록 하고, JWT에도 이 식별자 값을 같이 전달하여 JWT 인증 필터에서 시큐리티 인증 객체에 식별자 값을 같이 저장하도록 했습니다. 이렇게 해야 토큰 삭제 요청 API를 호출하는 비즈니스 로직에서 정상적으로 `principalName`을 호출하고 OAuth 액세스 토큰을 추출할 수 있었습니다.

 

📌 정리

OAuth의 인증 처리 과정을 디버깅하면서 발생한 문제의 원인을 파악하고 방법을 고민하여 해결할 수 있었습니다. 

같은 고민을 하고 계시는 다른 분들에게 조금이나마 도움이 되었으면 좋겠고, 더 좋은 의견 주시면 감사하겠습니다.

'트러블슈팅' 카테고리의 다른 글

[Redis] 캐시 스탬피드 현상  (0) 2025.12.14
[Spring WebSocket] STOMP - convertAndSendToUser 알고 사용하기  (0) 2025.11.04
쿠키 Samesite 설정으로 이슈 해결하기  (0) 2025.10.19
JpaRepository에서 default 키워드를 사용할 때 주의점  (0) 2025.10.19
'트러블슈팅' 카테고리의 다른 글
  • [Redis] 캐시 스탬피드 현상
  • [Spring WebSocket] STOMP - convertAndSendToUser 알고 사용하기
  • 쿠키 Samesite 설정으로 이슈 해결하기
  • JpaRepository에서 default 키워드를 사용할 때 주의점
이런개발
이런개발
geun-00의 흔적 보관소
  • 이런개발
    내일이 기대되는 오늘
    이런개발
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 백엔드 면접
      • SQL N
        • SUM, MAX, MIN
        • SELECT
        • GROUP BY
        • JOIN
      • Spring
      • JPA
      • 트러블슈팅
      • Infra
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백엔드 면접
    raid
    티스토리챌린지
    자바
    스프링
    오블완
    토스 페이먼츠
    JPA
    데브코스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
이런개발
Spring OAuth AccessToken 제대로 추출하기
상단으로

티스토리툴바