Song[coding diary index]

Song 배열에 코딩 흔적 남겨두기

spring

[EP 1-4] Spring 소셜로그인(OAuth2) 써보기1: 소셜로그인 완벽 이해하기

singsangssong 2025. 3. 13. 23:18
반응형

시작하기 전...

프로젝트에서 앱스토어와 플레이스토어 배포를 위해서 소셜로그인을 개발해야했다.(특히 Apple로그인은 안만들면 리젝당하니...)

Google, Apple 2가지 소셜로그인을 구축하고, 자체 회원가입은 구현하지 않도록 했다.

각 플로우차트를 설명하고, 이후 코드를 통해 설명하겠다.

 

이 글은 총 3편으로 1)이해, 2)SDK ver., 3)Backend ver.로 구성될 예정이다.

 

🍀내가 겪었던 모든 소셜로그인 삽질을 다른 사람들이 겪지 않기를 바라는 마음으로 이 글을 작성한다.🍀

기본적인 소셜로그인 플로우

들어가기 앞서, 소셜로그인 자체를 구현할 때 크게 거치는 과정이 존재한다. 

인증 서버, 리소스 서버는 각각 소셜로그인을 제공하는 회사에서 운영하며, 대부분 아래 틀과 같은 플로우를 거친다.

 

1. 로그인 요청: 사용자가 소셜로그인 화면을 통해 로그인을 요청한다.

2. 인증코드 발급: 1번 요청은 인증 서버에서 인증 코드를 발급한다.

3. Access 토큰 발급: 2번에서 받은 인증코드를 통해 사용자임을 인증하고, 리소스 서버에 접근할 수 있는 Access 토큰을 발급받는다.

4. 유저정보 발급: Access 토큰을 이용해서 리소스 서버에 요청을 보내면, 사용자의 정보를 받아 해당 정보를 우리 서버에서 저장한다.

5. 로그인 완료: 해당 사용자의 유저정보를 확인하고, 세션, jwt 방식을 통해 로그인 요청에 대한 응답을 완료한다.

 

소셜로그인을 제공하는 회사마다 방식이 조금씩 다르지만, 대부분 위 틀을 유지한 채로 수행한다. (Apple은 유독 유별나지만...)


프론트 vs 백 사이의 책임분배

이때, 위 처리를 프론트와 백엔드 사이에서 어디서 해줘야 하는지에 대한 고민을 해볼 수 있다!

 

💡위 1~5 과정을 프론트와 백이 나눠서 진행하게 되면, 유저의 보안정보를 가진 토큰이나 코드값을 탈취할 수 있기 때문에 한쪽에서 모든 정보를 처리하는 것이 가장 바람직한 방향이다!💡

프론트에서 처리한다면?

개발자 유미 이미지 참조

위처럼 모든 플로우를 프론트에서 도맡아 수행하는 방식이다. 이때, 서버는 유저정보만을 받고 로그인 방식에 따라 세션이나 jwt처리를 수행하면 된다. 서버 입장에서는 마치 자체 로그인을 처리하는 것과 차이가 없다. 대신 프론트에서 보낸 요청의 유저정보에 대한 진위여부를 판단해야한다. (프론트: 1~4번 과정 / 백: 5번 과정만)

백에서 처리한다면?

개발자 유미 이미지 참조

위는 모든 플로우를 서버에서 처리하는 모습이다. 프론트에서는 API요청만 보낸다면, 로그인 화면은 리다이렉트 uri를 통해서 로그인 화면을 서버에게 제공받는다. 이후 로그인 요청을 보내면 모든 처리를 서버에서 수행하고, 로그인 요청을 처리한다. (프론트: 1번만 / 백: 2~5번 과정)

 

이때, 네이티브(앱)라면 요청처리가 까다로운데,

1. redirect uri방식을 사용하기에 브라우저로 이동해야해서 UX적인 손해를 본다.

2. 또 쿠키를 다뤄야할때 네이티브에서 매우 불편하다고 한다....

(내가 이거때문에 고생고생을....)

 

우리의 선택은?

처음에는 백엔드에서 모든 책임을 처리하고, redirect uri방식을 채택했다. 소셜로그인에 관해 충분히 공부하고 싶었고 모두가 동의했으나...

UX적으로 좋지 않다는 평가를 받고, 결국 SDK 방식을 선회한다... (구현 다 끝나고 선회한건 안비밀)

 

이떄, 조금 특이하게(?) 동작하는 것 같은데, 방식에 관련된 조언을 해주고싶다면 댓글로 말씀해주시길...

앱에서는 SDK를 통해서 인증코드를 발급받음으로서, 플로우의 1, 2번을 앱에서 처리하고

서버에서는 요청받은 인증코드의 유효성을 확인한 뒤, 리소스 서버에 유저정보를 가져온다. 

(프론트 1~2번과정 / 백 2~5번과정) -> 2번과정이 중복됨...

 

만약 프론트에서 받은 SDK 인증코드를 서버로 요청보낸 뒤, 서버에서 프론트의 인증코드를 바탕으로 리소스 서버에 요청을 보낸다면 인증코드의 유효성이 없기에 유저정보를 받아올 수 없다! 

 

 

(백엔드에서 처리한 코드는 spring-oauth2-client를 이용했고, spring에 매우 종속적이며 깔끔한 코드임. 하지만 SDK는 조금 더럽다...)

 

다음 글에서는 구글로그인과 애플로그인 SDK version으로 어떻게 코드를 구성했는지 작성해볼 예정이다!

(글 쓰는 중...)

 

피드백, 충고, 댓글, 조언, 지적 모두 언제나 환영입니다!