[OpenID Connect] 카카오 로그인과 아마존 Cognito 연동 - Hosted UI 설정까지

웹 개발/사용자 경험

2022. 09. 15.

카카오 로그인 & 아마존 Cognito 연동하기

OIDC

OpenID Connect는 OAuth2 확장이야. 인가 서버에게 openid 스코프를 요청함으로써 추후 Access Token, Refresh Token 말고도 Identity Token을 발행 받게 되지. ID 토큰엔 기본적인 유저 어썰션이 담겨 있으니 세션 대용 뿐만 아니라 유저 정보 획득에도 쓸 수 있어. 한 편, OIDC 리소스 서버는 UserInfo 엔드포인트를 노출하는데, Access Token을 보여주면 거기에 대응된 유저 정보를 받아올 수 있어. 

 

앱에 '신속한 회원 가입'을 도입할 때 OAuth만으로 충분하긴 하지. 근데 유저 정보 습득을 하려면 해당 벤더의 특화된 API를 후속적으로 호출하게 될 거야. OIDC는 유저 정보를 획득하는 절차와 유저 정보 응답을 표준화했으니, 개발자가 벤더 의존적인 API 및 데이터 스키마에 결합되지 않게 해 줘. API 표준화를 주창하신 레오나르도 리차드슨 씨가 좋아하실 것 같다.

 

Amazon Cognito

앱에 회원 가입 · 유저 인증 · 로그인 화면 · 써드파티 신분 제공자(Amazon, Facebook, OIDC 제공자)와의 통합을 도입해야 한다면 아마존 CUP(Cognito User Pool)를 이용해 볼 수 있어.

 

유저 풀을 서버리스 환경에서 구성할 수 있고, OAuth2 혹은 OIDC 스펙을 준수하니 해당 사양을 지원하는 Spring Security 프레임워크와 통합할 수가 있지.

 

더불어 Hosted UI라고, 로그인 화면을 만들어서 써드 파티 로그인 버튼들도 만들어 주는데, 여기에 국내 MAU 4,700만명을 보유하는 카카오 로그인을 연결해 보면 재밌을 거 같아. 그래서 이 글에서 실습을 해 보자.

 

카카오 로그인 & OIDC 관련 사담

https://devtalk.kakao.com/t/openid/34746/5

 

카카오톡은 OpenID를 지원하지 않나요?

OpenID Connect 기능이 개발되어 안내드립니다. 관련 내용은 아래 가이드를 참고해주세요. SDK의 경우, OIDC 스펙이 적용된 아래 버전부터 사용할 수 있습니다. JavaScript SDK: 1.41.2 이상 iOS SDK: 2.9.0 이상 (

devtalk.kakao.com

한 때, 카카오 로그인에 아직 OIDC을 지원하는 API가 없었어. CUP랑 카카오 로그인은 OAuth2로 연동될 수는 없고, OIDC를 통해 연동해야 하지. 그래서 카카오 디벨로퍼스 데브톡에 OIDC가 있느냐고 문의를 했었어. 얼마 뒤 운이 좋게도, 담당자 분께서 OIDC 사양을 지원하게 됐다면서 기능 피드백을 주셨어. 정말 감사할 따름이었다.

 

다만, 초반 릴리스 때 OIDC 사양의 엄격한 준수가 이뤄지지 못 했고, CUP랑 연동하는 데 몇 가지의 이슈가 생겼지. 나는 관련자 분들과 함께 이슈를 추적했어.

 

이런 고생 끝에 잘 검증된 카카오 로그인의 OIDC를 쓸 수 있게 됐지만, 당시 내가 진행하던 프로젝트('여행 비서 페이몬')가 사실 웹 서비스 기획에서 챗봇 서비스로 엎어졌었거든. 그래서 실제 CUP랑 연동을 해 볼 수는 없었어.

 

오늘 오랜만에 데브톡 이슈를 다시 읽게 됐는데, 그 때 기억이 떠오르네. 실습을 하고픈 기분이 들어서 여기에 글로 남길게.

전제사항

  • 카카오 디벨로퍼스에 앱 등록이 돼 있어야 해. 또, 앱 키클라이언트 시크릿이 할당되어 있어야 하고.

카카오 디벨로퍼스> 내 애플리케이션> 앱 키
카카오 디벨로퍼스> 내 애플리케이션> 보안

  • 이 글은 profile_nickname · account_email 두 가지를 동의항목으로 해서 연동을 테스트 할 거야. 종막에 카카오 유저의 닉네임과 이메일 주소를 Cognito 유저 풀로 가져오게 되겠지.

카카오 디벨로퍼스> 내 애플리케이션> 동의항목

진행 순서

  1. 아마존 Cognito에서 유저 풀을 생성한다.
  2. Cognito에 클라이언트 앱을 등록한다.
  3. Cognito에 연합 신분 제공자로서 카카오 로그인을 등록한다.
  4. 클라이언트의 Hosted UI를 설정하고 접속해 본다. 카카오 로그인 버튼이 생기는 지 확인한다.
  5. 카카오 로그인의 OIDC가 내려주는 속성과, 우리 유저 풀의 속성을 매핑한다.
  6. Cognito와 카카오 로그인이 OIDC 플로우를 탈 수 있도록, 카카오 측에 Callback URL을 등록한다.
  7. Hosted UI에 접속하고 카카오 로그인을 진행한다. 카카오 유저 정보를 토대로 한 신규 유저가 Cognito User Pool에 생성됨을 확인하자.

1. 아마존 Cognito User Pool 생성

아마존 관리 콘솔에 접속해서 Cognito User Pool을 생성해보자.

로그인 경험 설정

보이는 대로 설정을 따라해 줘.

Sign-in experience 설정

보안 요구사항 설정

체크하는 설정에 따라서, 내 유저가 갖춰야 할 필수적인 Attribute가 생기게 돼. 단순한 데모를 위해 E-MAIL 및 SMS 정보를 필수로 만드는 설정들을 피해 가려고.

Security Requirements 설정

회원가입 경험 설정

보이는 대로 설정을 따라해 보면, 최종적으로 Required Attributes가 비게 될 거야.

실사용 될 유저 풀이라면 앞서 진행한 설정을 따르지 않아도 무리가 없어. 설정을 숙고해서 결정하는 게 좋아.

Sign-up experience 설정

이메일 발송 설정

역시 단순함을 위해 간단한 설정을 할게.

Email Delivery 설정

2. Cognito에 클라이언트 앱 등록

앱 통합 설정

아직 유저 풀 만들기 화면을 벗어나지 않았어. 다음 단계에서는 Cognito의 유저 풀을 이용할 클라이언트 앱을 등록하는 거야. 이건 OAuth2에서 클라이언트를 리소스 서버에 등록하는 것과 동일한 개념이지.

App Integration (1)
App Integration (2)

그림과 같이 Client 앱을 CUP에 등록했어. 콜백 엔드포인트 등록을 하라는데, 이 엔드포인트는 우리 앱과 Cognito 사이의 OAuth2 혹은 OIDC 플로우를 지원하는 백엔드와 연결되어야 해. 지금 당장은 바르게 동작하지 않아도 괜찮아.

 

나중에 유저가 CUP에 로그인 하면, CUP의 인가 서버가 Authorization Code를 발행해 줄 거고, 방금 등록한 엔드포인트로 리다이렉트 시켜줄 거야. 그럼 그 쪽 백엔드는 CUP의 Token Endpoint와 대화해서 Access Token · Refresh Token · 선택적으로 Identity Token를 교환하고 결국 유저 에이전트에게 세팅해 주겠지. 즉 OAuth에서 하던 그 플로우라는 거 알겠지?

 

3. 카카오 로그인을 OIDC 제공자로 등록

이제 카카오 로그인을 연합 신분 제공자로서 등록할게. 코그니토는 Amazon · Google · Meta 등의 OAuth2 제공자와는 훨씬 간편한 설정으로 연동되는데, 카카오는 그렇지 않아서 OAuth2 확장인 OIDC 스펙을 통해 연동해야 해.

 

걱정 마. 카카오는 OIDC 디스커버리 스펙을 구현했어. 연동에 필요한 메타 정보를 제공하고 있지. 디스커버리를 사용하면 4가지 엔드포인트(인가 · 토큰 · 유저정보 · jwks)를 우리가 직접 입력하지 않아도 돼! 그냥 issuer 정보만 넣으면 CUP가 그들을 전부 파악할 거야.

 

다음 설정을 따라해 보자.

OIDC 제공자 등록하기

ID 제공자 추가를 클릭하자
연합 신분 제공자 유형을 OIDC로 선택
카카오 디벨로퍼스에 등록한 클라이언트 정보를 토대로 설정한다. 이 글 앞쪽의 전제사항을 확인 바란다.
Issuer URL을 카카오 것으로 입력하고 버튼을 클릭해 ID 제공자를 만든다. 디스커버리 덕분에 필요 설정들이 알아서 채워질 것이다.

등록 잘 됐는지 확인하기

카카오 로그인 아이디 제공자가 잘 생성됐는지 확인

4. 우리 클라이언트의 Hosted UI 설정

App Integration> App clients and analytics로 가서 아까 만들었던 클라이언트를 클릭해 줘. 스크롤을 조금 내리면 Hosted UI가 있어. 얘의 수정 화면으로 진입한 다음 카카오 로그인을 신분 제공자로 추가해 주렴. 

 

이제 설정 화면을 나와서 클라이언트 앱의 로그인 UI가 어떻게 됐을지 보자. 정말 카카오 로그인 버튼이 생겼을까?

App Integration> App clients and analytics> 만들었던 클라이언트 클릭> View Hosted UI를 클릭

우리의 Hosted UI에 카카오 로그인 버튼이 보이고 있어. 마찬가지로 Amazon, Google, Meta 등 다수의 신분 제공자와 연동하여 로그인 버튼 여럿을 전시하는 게 가능해.

Hosted UI에 카카오 로그인 버튼이 있는지 확인!

5. 카카오 디벨로퍼스에 Callback URL 등록하기

유저가 우리 Hosted UI를 거쳐 카카오로 이동하고, 거기서 카카오 계정 로그인을 성공적으로 완수했다 치자. 그럼 CUP는 카카오와 나머지 OIDC 플로우를 투명하게 진행해야 해. Identity Token 획득 후 UserInfo를 가져오는 플로우 말야.

 

그것이 오류 없이 일어나려면 CUP 측의 Callback URL을 카카오 디벨로퍼스에 있는 내 앱에 등록해 줘야겠네. 조심해 우리네 Callback URL 등록이 아니야...

 

아까 CUP 클라이언트의 도메인 만들었지? 그 뒷부분에 '/oauth2/idpresponse'를 붙여주도록 해.

카카오 디벨로퍼스> 내 앱> 카카오 로그인> Redirect URI 등록> /oauth2/idpresponse 붙이자

6. 유저 풀과 카카오 로그인 간 속성 매핑하기

CUP 콜백이 카카오 측 정보를 받아 우리 유저 풀에 유저를 신규하려면, 카카오가 내려준 유저 정보 클레임을 우리네 유저 속성과 매핑할 수 있어야 해.

 

해당 매핑 설정을 우리가 코그니토 콘솔에서 해 줄거야. 아래 이미지처럼 설정해 줄 수 있어. 

Sign-in experience> Federated Id Provider> KakaoLogin> Attribute mapping 수정

저지르기 쉬운 실수는, 가리킨 위치에 카카오 로그인의 OAuth 스코프 profile_nickname, account_email 등을 쓰는 행위야. OIDC에서 정의한 표준 클레임 및 카카오가 추가 정의한 커스텀 클레임을 넣는 자리니까. 카카오 로그인의 UserInfo 엔드포인트 API 명세를 꼭 참고하도록 하자.

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

7. Hosted UI에서 카카오 로그인 - 신규 유저 생성 확인

6번을 마치고 카카오 계정 로그인을 진행해 볼래? CUP와 카카오 로그인 사이의 OIDC 플로우가 투명하게 진행되어, 결국 Cognito 유저 풀에 유저가 새로이 생성되었어.

신규 유저 확인!

이렇게 7번까지 진행해서 CUP와 카카오 로그인을 OIDC 스펙으로 연동시킬 수 있음을 확인했네. 결과적으로 카카오 유저 정보를 빼 와서 우리의 유저 풀에 새 유저로 이식할 수 있었어. 웹 사이트의  '빠른 회원가입' 기능을 이렇게 구현해 볼 수 있겠다.

8. (Additional) Cognito와의 OAuth · OIDC 플로우

카카오를 통한 로그인 이후부터 내 클라이언트 앱과 CUP 사이의 인증 플로우를 진행하면 돼. GIF 이미지를 보자. 인가 코드와 함께 내가 등록했던 콜백 URL로 302 Redirect가 발생하는 걸 알 수 있지.

 

이제 발급 받은 인가 코드와 함께, CUP 측의 Token Endpoint와 대화해서 액세스 토큰 · 리프레시 토큰 · 아이디 토큰으로 교환하고 그들을 유저 에이전트에게 내려주면 되겠어. 관련한 추가 구현은 친우의 재량에 맡길게. 그럼 나중에 또 보자.

카카오 로그인 성공! Cognito 측과의 OAuth 플로우 시작 (인가 코드 발급된 걸 볼 수 있음)