[OAuth] 프론트/백의 소셜로그인 협업

우노·2024년 6월 13일
2

OAuth

목록 보기
3/4
post-thumbnail

[OAuth] 소셜로그인을 위한 OAuth 2.0를 이해했다면 이제 개발에서 구현할 차례입니다!

아래 사진에서 Application의 역할을 구현해야하는데 그럼 여기서 질문이 생길 수 있겠죠.
1. 그거 어떻게 구현하는 건데..?
2. 그래서 나는 뭘 해야하는데...?

1번은 이전 글의 로직을 바탕으로 공식 문서를 읽으면서 소셜로그인 제공업체의 OpenAPI를 호출해서 데이터를 가져오면 됩니다. 결국 구조를 이해하면 트러블슈팅의 문제이므로 다음 글에서 정리하고 이 글은

소셜로그인 협업에서 프론트/백을 맡으면 해야할 일

에 대해서 풀어보려고 합니다! 그 전에 한 가지만 확실하게 짚고 넘어가시죠.

Redirection

리디렉션이란 간단히 말해 다른 URL로 이동시키는 것입니다.

구글은 웹 애플리케이션 세팅에서 승인된 리디렉션 URI에 다음과 같은 설명을 첨부했습니다.

사용자가 Google에서 인증을 받은 후 이 경로로 리디렉션됩니다. 이 경로는 뒤에 액세스용 승인 코드가 추가되며 프로토콜이 있어야 합니다. URL 조각, 상대 경로, 와일드 카드는 포함할 수 없으며 공개 IP 주소는 사용할 수 없습니다.

더하여 redirect_uri는 API 서버가 사용자를 리디렉션하는 위치로 설명합니다.
상황을 가정해서 위의 글을 이해해봅시다!

  1. 우리는 구글 로그인을 하기 위해서 1️⃣ 구글 로그인 페이지로 이동시킵니다.
  2. 구글에서는 인증 이후 2️⃣ 내 서비스 페이지에 인가 코드를 담아 이동시키면서 데이터를 전달합니다.

💡 결국 승인된 리디렉션 URI데이터를 전달받을 페이지이자 실행할 엔드포인트의 역할 을 수행합니다.

🚧 여기서 놓치지 말아야할 점은 리디렉션 시키면 끝!!! 이라는 점입니다. A→B로 리디렉션 시켰는데 A의 상태를 유지한 상태로 다시 B→A로 돌아와서 A에서 뭔가를 수행할 수는 없습니다 !


가장 헷갈리는 부분을 짚었으니 이제 프론트-백이 소셜로그인을 구현하는 방식 두가지를 소개하겠습니다. 사실 이 두가지 방식 이외에도 인가코드, 액세스토큰, 리디렉션만 잘 이해한다면 자유롭게 구현해도 문제 없습니다!

1️⃣ 인가 코드-FE | 액세스 토큰-BE

소셜로그인 제공업체에 인가 코드는 프론트가, 액세스 토큰은 백엔드가 요청하는 방식입니다.

✅ 프론트엔드 To-Do List

  1. 소셜로그인 제공업체 로그인 페이지 연결하기
  2. redirect_uri 프론트엔드 주소로 설정해서 인가 코드 받기
  3. redirect_uri로 설정한 엔드포인트에서 인가 코드를 담아 백엔드 API 호출하기
    Google의 OAuth 2.0 서버로 리디렉션하기

✅ 백엔드 To-Do List

  1. 프론트엔드에서 인가코드 받기
  2. 인가 코드로 액세스 토큰 요청하기
  3. 액세스 토큰으로 데이터 요청하기
  4. 제공업체 데이터 활용해서 프론트엔드에 응답 반환하기
    승인 코드를 갱신 토큰 및 액세스 토큰으로 교환

각 역할별로 수행해야할 과정을 설명하는 구글 디벨로퍼스 링크를 첨부했습니다.

투두리스트를 보면 알 수 있듯이 이 방법에서 백엔드의 API는 프론트엔드가 요청하면 그에 맞는 응답을 반환하는 보통의 백엔드 API와 동작 방식이 같고 중간에 OpenAPI를 여러번 호출하는 것 이외에는 특이점이 없습니다.

redirect_uri

다만 한 가지 주의해야할 점은 인가 코드와 액세스 토큰을 호출할 때 써야하는 쿼리 매개변수입니다. 구글을 예시로 들면 각 요청마다 필수적으로 전달해야할 쿼리 파라미터는 다음과 같습니다.

인가 코드 요청

  • client_id: 클라이언트 식별자
  • redirect_uri: API 서버가 사용자를 리디렉션하는 위치
  • response_type: 권한 부여 방식 지정 (code)
  • scope: 사용자에게 허가받을 데이터 범위

액세스 토큰 요청

  • client_id: 클라이언트 식별자
  • client_secret: 클라이언트 보안 비밀번호
  • code: 인가 코드
  • grant_type: 지정한 권한 부여 방식 (authorization_code)
  • redirect_uri: 기등록된 리디렉션 URI 중 하나

redirect_uri는 승인 코드(인가 코드)를 전달받는 URI입니다. 하지만 액세스 토큰 요청에도 승인된 리디렉션 URI에 미리 등록된 URI 중 하나를 전달해야합니다..!

이 과정에서 아직 액세스 토큰의 redirect_uri가 어떤 역할을 하는지 직접 케이스별로 테스트해보지는 못했으나 크게 두가지 역할을 할 것 같습니다.

  • [redirect_uri마다 인가 코드가 달라진다면] 인가 코드로부터 인증 정보를 가져오기 위한 복호화 KEY 역할
  • [항상 동일한 인가 코드라면] client_id, client_secret과 더불어 적절한 요청인지 확인하는 역할

❗ 결국 중요한 점은 이 방식에서 redirect_uri는 인가 코드를 전달받아 백엔드 API를 호출할 프론트엔드 엔드포인트로 설정하고 백엔드에서 액세스 토큰을 요청할 때에도 이 방식을 써야한다는 점입니다.


멋사 중앙대 위키를 이 방식으로 구현했고 아래는 세션 때 쓰려고 만들었던 자료인데 이해에 참고하시면 좋을 것 같아 첨부했습니다!

2️⃣ 인가 코드-BE | 액세스 토큰-BE

소셜로그인 제공업체에 인가 코드와 액세스 토큰 모두 백엔드가 요청하는 방식입니다.

✅ 프론트엔드 To-Do List

  1. 로그인 버튼에 로그인 시작하는 백엔드 API 연결하기
  2. redirect_uri 프론트엔드 주소로 설정해서 인가 코드 받기
  3. redirect_uri로 설정한 엔드포인트에서 인가 코드를 담아 백엔드 API 호출하기

✅ 백엔드 To-Do List

  1. 구글 로그인 페이지로 리다이렉트 시키기
  2. 인가 코드로 액세스 토큰 요청하기
  3. 액세스 토큰으로 데이터 요청하기
  4. 제공업체 데이터 활용해서 프론트엔드에 응답 반환하기
    Google의 OAuth 2.0 서버로 리디렉션하기
    승인 코드를 갱신 토큰 및 액세스 토큰으로 교환

뭐가 달라졌는지 틀린 그림 찾기를 하고 있다면 정답은

소셜로그인 제공업체 로그인 페이지로 누가 REDIRECT 해주는지

입니다. 1번에서는 프론트가 프론트→로그인 페이지 로 연결했다면,
2번에서는 프론트→백→로그인 페이지 로 연결됩니다.

redirect_uri

인가 코드를 백엔드가 요청한다면 redirect_uri도 백엔드로 설정해야하나요?

❌ 아닙니다! 만약 그렇게 설정한다면 소셜로그인이 끝나고 갑자기 백엔드 서버 페이지로 이동하는 불상사를 겪게 됩니다.. 어떻게 알았냐면 저도 알고 싶지 않았습니다^^...

앞선 글을 다시 가져왔습니다.

🚧 여기서 놓치지 말아야할 점은 리디렉션 시키면 끝!!! 이라는 점입니다. A→B로 리디렉션 시켰는데 A의 상태를 유지한 상태로 다시 B→A로 돌아와서 A에서 뭔가를 수행할 수는 없습니다 !

이 방식에서는 백엔드 → 구글 페이지로 이동했는데 다시 리디렉션을 수행한 백엔드의 위치로 돌아와서 백엔드가 무언가를 더 수행할 수 없는 상황이 되겠죠!? 리디렉션 시키면 끝!!! 이니 구글도 redirect_uri를 설정해서 해당 주소로 데이터를 넘겨주지 리디렉션 시킨 곳으로 넘겨줄 시도를 하지 않습니다.

그래서 redirect_uri는 1번과 동일하게 프론트엔드로 설정해서 해당 프론트엔드 엔드포인트에서 함수를 실행하여 전달받은 인가 코드와 함께 백엔드 API를 호출합니다.
가장 간단하게는 인가 코드 요청만 백엔드가 한다! 로 이해하시면 쉬울 것 같습니다!


위의 방식을 이해하셨다면 이미 아시겠지만 도식화 했을 때의 흐름은 1번과 흡사합니다! 누가 로그인 페이지를 연결하느냐의 차이인 것이죠.

비교

결국 프론트→로그인 페이지 vs 프론트→백→로그인 페이지 입니다.
정량적인 비교보다는 두 방법을 모두 시도해보면서 느낀 정성적인 비교를 적어보려 합니다.

프론트 → 로그인 페이지

  • 호출과 협업에 있어 신경 쓸 부분이 줄어듭니다.

기존 프론트엔드와 백엔드가 협업하는 방식 요청 & 응답 방식을 그대로 활용하면서 각자 OpenAPI를 활용한다는 점에서 쿼리 파라미터만 잘 설정하면 끝 !

프론트 → 백 → 로그인 페이지

  • 각자 맡은 역할과 하는 일이 명확해집니다.

프론트엔드가 "로그인 페이지로 리다이렉트한다." 보다는 단순히 "백엔드 API를 호출한다."가 프론트/백의 역할과 관계가 보다 뚜렷하게 나타나는 것 같습니다.

  • 비밀 값 관리가 수월해집니다.

client_id, client_secret 과 같은 값을 프론트/백이 공유해서 사용하는 것보다는 백엔드 혼자 사용하는 점이 훨씬 노출의 위험이 적겠죠. 사담이지만 백엔드를 맡다가 프론트엔드 코드를 처음 보고 놀랐던 점이 .env 파일이나 secrets.json 같은 파일을 덜 활용한다는 점이었어서 그런 의미에서도 백엔드가 관리하는 게 편할 것 같다는 의견입니다.


"프론트-백의 소셜로그인 협업" 이라는 거창한 제목을 내세웠지만 결국 로그인 페이지를 누가 연결하는지redirect_uri가 이 글의 주제이고 이 두가지를 잘 협의해서 원활하게 협업하시면 좋을 것 같습니다! 가장 중요한 점은 로그인을 모두 마치고 Redirect는 프론트로 돌아와야한다는 점입니다!

다음 소셜로그인 글은 '그래서 코드를 어떻게 쓰라고..?'에 대한 답으로 작성해보겠습니다. 문제가 있거나 틀린 부분은 조언, 지적 부탁드립니다..!⚡

profile
기록하는 감자

0개의 댓글