[Spring Security] OAuth 2.0으로 소셜 로그인 구현하기

이준영·2024년 12월 24일

Spring MSA 프로젝트

목록 보기
8/15
post-thumbnail

개요

Spring Security를 활용하여 accessToken, refreshToken 발급을 구현해 보았다.
이번에는 OAuth2를 활용한 소셜 로그인을 프로젝트에 적용해보려고 한다.

강의 정리

강의 : https://www.inflearn.com/course/web2-oauth2

생활 코딩 강의를 들으며 이론적인 내용을 정리해보았다.

소개

구글 등 기존 서비스를 우리 서버에서 사용자들에게 제공할 수 있도록 하는 도구

역할

Resource Server : 자원(데이터)을 가진 서버 (구글)
Authorization Server : 인증 관련 처리를 전담하는 서버
Resource Owner : 자원의 소유자 (사용자)
Client : Resource Server의 자원을 활용하는 우리 서버

등록

Client ID / Client Secret : 클라이언트 등록을 위한 정보
Authorized redirect URIs : Authorize Code를 전달하는 주소

Resource Owner의 승인

  1. Resource Owner -> Resource Server
    • client Id, scope(사용 할 기능), redirectUri 전달
  2. Resource Owner <- Resource Server
    • 로그인 요청
  3. Resource Owner -> Resource Server
    • 로그인
  4. Resource Server
    • client Id와 redirect_uri 확인
  5. Resource Owner <- Resource Server
    • scope에 대한 권한 허용할건지 확인 요청
  6. Resource Owner -> Resource Server
    • 허용 확인
  7. Resource Server
    • user Id가 client Id에게 scope에 대한 권한 허용했음을 저장

Resource Server의 승인

  1. Resource Owner <- Resource Server
    • authorization code 전달
  2. Resource Owner -> Client
    • authorization code 전달
  3. Client -> Resource Server
    • grant_type, authorization code, redirect_uri, client_id, client_secret 전달
  4. Resource Server
    • Client로부터 전송 받은 정보 일치 여부 확인

액세스 토큰 발급

  1. Resource Server
    • Authorication Code 삭제
    • AccessToken 발급(user id에게 scope에 대한 권한이 있음을 확인가능)
  2. Client <- Resource Server
    • AccessToken 전달

API 호출

Application Programming Interface

예를들어 구글의 어떤 기능을 사용하려면 Google API를 활용하여 구현 할 수 있다

리프레쉬 토큰

RFC : 인터넷 관련 기술 표준안
https://datatracker.ietf.org/doc/html/rfc6749#section-1.5

Spring Security OAuth Client

강의를 보며 OAuth2의 구조를 잘 이해할 수 있었다.
실제 Spring으로 구현하는 방법은 아래 영상을 참조했다.
https://www.youtube.com/playlist?list=PLJkjrxxiBSFALedMwcqDw_BPaJ3qqbWeB

Spring Security OAuth Client 의존성 추가 후
SecurityConfig에 다음과 같은 코드를 추가하면 간단하게 구현할 수 있다.

http.oauth2Login(Customizer.withDefaults());

그리고 application.yml에서 사용하고자 하는 provider(구글, 페이스북, 네이버, 카카오 등) 정보를 작성하면 된다.

하지만 현재 프로젝트에서는 accessToken, refreshToken 검증을 거쳐 api를 활용할 수 있도록 하였기 때문에 추가적인 토큰 발급 로직이 필요하다.

http.oauth2Login(oauth2 -> oauth2
                .userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig
                        .userService(customOAuth2UserService))
                .successHandler(oAuth2Handler)
                .failureHandler(oAuth2Handler));
  • successHandler : oauth 로그인 성공 시 토큰을 발급
  • failureHandler : oauth 로그인 실패 시 커스텀 응답 객체 응답
  • 이후 서비스 기능 사용 시 독립성을 향상 시키기 위하여 DefaultOAuth2UserService의 loadUser를 Override하여 최초 로그인 시 db에 사용자 정보를 저장 하도록 userService를 등록 해주었다.

개선 사항

구현 방법은 위 영상에서 너무 잘 알려주고 있어서 자세히 설명하지 않고 구현 후 현재 프로젝트의 문제점과 개선방안에 대해서 이야기 해보려 한다.

user-service : 사용자 등록, 조회, 수정, 삭제 및 로그인(일반 로그인/oauth 로그인), 로그아웃 담당

첫번째 문제는 user-service에 많은 책임이 집중 되어 있다는 점이다. 이를 해결하기 위해 인증 모듈을 추가하여 로그인, 로그아웃 기능을 담당하도록 해야겠다 생각했다.

두번째 문제는 모든 요청을 api-gw에서 받아 micro service로 라우팅 처리 하고 있는데 oauth 로그인의 경우 포트 번호가 다르면 이후 oauth 플로우에 영향을 미쳐 직접 user-service 포트로 요청을 보내야한다. 물론 api-gateway 포트와 user-service 포트를 열어두고 그렇게 사용할 수도 있겠지만 위에서 말한 인증 모듈을 만들어 이 두번째 문제도 해결 할 수 있을 것 같아 인증 모듈을 만들기로 결정하였다.

  • api-gateway
  1. 토큰 검증 위임 -> auth-service
  2. 그 외 모든 api 라우팅 처리
  • auth-service
  1. api-gateway로부터 토큰 검증 위임 받아 처리
  2. 로그인, 로그아웃 기능 직접 요청 받아 처리
  • user-service
  1. 사용자 등록, 조회, 수정, 삭제 기능 담당

토큰 검증 처리를 auth-service에서 위임받아 처리 할 지
api-gateway에서 직접 처리할 지는 확실하지 않다. 조금 더 알아봐야겠다.

마치며

드디어 user-service가 아닌 새로운 micro service를 추가하게 되었다.
새로운 micro service를 추가하게 되면서 openFeign을 사용할 수 있는 경우가 있다면 사용 해볼 예정이다.
잠깐 살펴본거긴 하지만 높은 이해도가 필요해보여 미루고 있는 중이다...

슬슬 클라이언트 페이지도 추가해야할 타이밍인 것 같아 안드로이드 앱을 생각하고 있다.
간단한 로그인페이지와 마이페이지를 보여주면 좋을 것 같다.
이후 기능은 생각해보자.

profile
환영합니다!

0개의 댓글