[OAuth] 소셜로그인을 위한 OAuth 2.0를 이해했다면 이제 개발에서 구현할 차례입니다!
아래 사진에서 Application의 역할을 구현해야하는데 그럼 여기서 질문이 생길 수 있겠죠.
1. 그거 어떻게 구현하는 건데..?
2. 그래서 나는 뭘 해야하는데...?
1번은 이전 글의 로직을 바탕으로 공식 문서를 잘 읽으면서 소셜로그인 제공업체의 OpenAPI를 잘 호출해서 데이터를 잘 가져오면 됩니다. 결국 구조를 이해하면 트러블슈팅의 문제이므로 다음 글에서 정리하고 이 글은
소셜로그인 협업에서 프론트/백을 맡으면 해야할 일
에 대해서 풀어보려고 합니다! 그 전에 한 가지만 확실하게 짚고 넘어가시죠.
리디렉션이란 간단히 말해 다른 URL로 이동시키는 것입니다.
구글은 웹 애플리케이션 세팅에서 승인된 리디렉션 URI에 다음과 같은 설명을 첨부했습니다.
사용자가 Google에서 인증을 받은 후 이 경로로 리디렉션됩니다. 이 경로는 뒤에 액세스용 승인 코드가 추가되며 프로토콜이 있어야 합니다. URL 조각, 상대 경로, 와일드 카드는 포함할 수 없으며 공개 IP 주소는 사용할 수 없습니다.
더하여 redirect_uri
는 API 서버가 사용자를 리디렉션하는 위치로 설명합니다.
상황을 가정해서 위의 글을 이해해봅시다!
- 우리는 구글 로그인을 하기 위해서 1️⃣ 구글 로그인 페이지로 이동시킵니다.
- 구글에서는 인증 이후 2️⃣ 내 서비스 페이지에 인가 코드를 담아 이동시키면서 데이터를 전달합니다.
💡 결국 승인된 리디렉션 URI란 데이터를 전달받을 페이지이자 실행할 엔드포인트의 역할 을 수행합니다.
🚧 여기서 놓치지 말아야할 점은 리디렉션 시키면 끝!!! 이라는 점입니다. A→B로 리디렉션 시켰는데 A의 상태를 유지한 상태로 다시 B→A로 돌아와서 A에서 뭔가를 수행할 수는 없습니다 !
가장 헷갈리는 부분을 짚었으니 이제 프론트-백이 소셜로그인을 구현하는 방식 두가지를 소개하겠습니다. 사실 이 두가지 방식 이외에도 인가코드, 액세스토큰, 리디렉션만 잘 이해한다면 자유롭게 구현해도 문제 없습니다!
소셜로그인 제공업체에 인가 코드는 프론트가, 액세스 토큰은 백엔드가 요청하는 방식입니다.
각 역할별로 수행해야할 과정을 설명하는 구글 디벨로퍼스 링크를 첨부했습니다.
투두리스트를 보면 알 수 있듯이 이 방법에서 백엔드의 API는 프론트엔드가 요청하면 그에 맞는 응답을 반환하는 보통의 백엔드 API와 동작 방식이 같고 중간에 OpenAPI를 여러번 호출하는 것 이외에는 특이점이 없습니다.
다만 한 가지 주의해야할 점은 인가 코드와 액세스 토큰을 호출할 때 써야하는 쿼리 매개변수입니다. 구글을 예시로 들면 각 요청마다 필수적으로 전달해야할 쿼리 파라미터는 다음과 같습니다.
인가 코드 요청
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는 인가 코드를 전달받아 백엔드 API를 호출할 프론트엔드 엔드포인트로 설정하고 백엔드에서 액세스 토큰을 요청할 때에도 이 방식을 써야한다는 점입니다.
멋사 중앙대 위키를 이 방식으로 구현했고 아래는 세션 때 쓰려고 만들었던 자료인데 이해에 참고하시면 좋을 것 같아 첨부했습니다!
소셜로그인 제공업체에 인가 코드와 액세스 토큰 모두 백엔드가 요청하는 방식입니다.
뭐가 달라졌는지 틀린 그림 찾기를 하고 있다면 정답은
소셜로그인 제공업체 로그인 페이지로 누가 REDIRECT 해주는지
입니다. 1번에서는 프론트가 프론트→로그인 페이지 로 연결했다면,
2번에서는 프론트→백→로그인 페이지 로 연결됩니다.
인가 코드를 백엔드가 요청한다면 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는 프론트로 돌아와야한다는 점입니다!
다음 소셜로그인 글은 '그래서 코드를 어떻게 쓰라고..?'에 대한 답으로 작성해보겠습니다. 문제가 있거나 틀린 부분은 조언, 지적 부탁드립니다..!⚡