OAuth

An open protocol to allow secure API authorization in a simple and standard method from web, mobile and desktop applications.

— OAuth 공식 사이트.

"카카오로 로그인", "Google로 로그인" 버튼 하나로 세상을 편하게 만든 일등공신. 그러나 직접 연동을 구현하려는 개발자에게는 Redirect URI 매칭 실패와 각종 토큰 교환 오류의 무한 루프를 선사하는 주범

1. 개요

OAuth(OAuth 2.0)는 제3의 서비스(Google, Kakao, Naver, Github 등)가 가지고 있는 사용자의 정보에 대해 우리의 서비스가 안전하게 접근 권한을 위임받기 위한 업계 표준 프로토콜이다.

과거에는 다른 사이트의 기능을 쓰려면 진짜 그 사이트의 ID와 패스워드를 수집해야 했으나, 이는 보안상 정신 나간 짓이었다. OAuth 덕분에 우리는 사용자의 비밀번호를 구경조차 하지 않고도 "이 사람이 철수라는 걸 Google이 보증해 줬다"라는 사실과 함께 프로필 이미지 정도만 안전하게 받아올 수 있게 되었다.

2. 역할군 및 인증 흐름

2.1. OAuth 2.0의 4가지 주요 역할군

OAuth를 이해하려는 개발자들의 뚝배기를 깨버리는 주범이다. 용어가 직관적이지 않아 처음에 엄청 헷갈린다.

  1. Resource Owner (자원 소유자): 서비스의 진짜 주인인 사용자.
  2. Client (클라이언트): 우리가 만드는 /앱 서비스.1
  3. Resource Server (자원 서버): 사용자의 정보(프로필 등)를 쥐고 있는 대기업 서버 (ex: 카카오 API 서버).
  4. Authorization Server (인증 서버): 토큰을 발급하고 인증을 처리해 주는 대기업 인증 서버.

2.2. 인증 흐름 (Authorization Code Grant)

가장 널리 쓰이는 시나리오는 다음과 같다.

  1. 사용자가 우리 앱에서 "구글로 로그인" 버튼을 누른다.
  2. 사용자는 구글 로그인 창으로 이동해 동의 버튼을 누른다.
  3. 구글은 사용자를 우리 앱의 Redirect URI로 돌려보내면서 임시 코드(Authorization Code)를 얹어 준다.
  4. 우리 [백엔드](backend)는 이 코드를 들고 비밀 키와 함께 구글 인증 서버로 달려가 진짜 액세스 토큰(Access Token)으로 교환한다.
  5. 이제 이 토큰을 사용해 사용자의 구글 프로필을 가져온다.2

3. 관련 밈 및 드립

3.1. Redirect URI Mismatch의 공포

OAuth를 구현해 본 개발자라면 평생 한 번쯤은 마주치게 되는 시뻘건 에러 화면이다. 구글이나 카카오 개발자 콘솔에 등록해 둔 Redirect URI와, 실제 우리 코드에서 요청을 보낼 때 명시한 redirect_uri 값이 스펠링 하나, 마지막 슬래시(/) 하나라도 다르면 얄짤없이 뿜어지는 에러다. 주로 개발 서버(http://localhost:3000)에서 실서버(https://my-app.com)로 배포할 때 설정을 깜빡해서 발생하며, 개발자는 자신의 눈을 의심하며 오타를 찾게 된다.3

3.2. 아이디 비번 넘겨주세요

OAuth의 기본 사상 자체를 이해하지 못한 타 부서나 협력업체가 종종 요구하는 무시무시한 조건이다. "연동 스펙이 너무 복잡하니까 그냥 사용자 ID/PW를 저희 API로 넘겨주세요. 저희가 알아서 처리할게요."라는 제안을 들으면, 보안 담당자와 백엔드 개발자는 뒷목을 잡고 쓰러진다.

4. 여담

  • 대한민국의 소셜 로그인 중독: 한국의 거의 모든 서비스는 이 OAuth를 활용한 네이버/카카오/페이코/구글/애플 로그인을 지원한다. 간편해서 좋지만, 가끔 내가 이 사이트에 어떤 계정으로 가입했는지 까먹어서 네이버로 로그인했다가, 카카오로 로그인했다가 하는 바람에 계정이 5개쯤 파이는 대참사가 벌어지기도 한다.
  • 탈모 방지용 OAuth 2.0: OAuth 1.0은 암호화 서명 방식이 너무 복잡해서 구현하다가 탈모가 올 지경이었다. OAuth 2.0으로 오면서 서명 로직을 빼고 단순한 HTTPS(SSL/TLS) 통신에 의존하게 되면서 개발 난이도가 매우 낮아졌다.
  • 인증과 인가의 결합 OIDC: OAuth는 본래 '인가(Authorization, 권한 부여)'를 위해 만들어진 스펙이다. 하지만 요즘은 다들 '로그인(Authentication, 신원 확인)' 용도로 쓰다 보니, 이 한계를 보완하기 위해 ID 토큰 개념을 추가한 OIDC (OpenID Connect) 규격이 탄생했다.

5. 관련 문서

각주

  1. 대기업(구글, 카카오 등) 관점에서의 클라이언트를 뜻하므로, 우리 백엔드 서버도 구글 입장에서는 'Client'가 된다.

  2. 이 복잡한 핑퐁 과정을 한 번이라도 직접 짜봐야 비로소 진정한 주니어 백엔드 개발자의 문턱을 넘었다고 볼 수 있다.

  3. "어제 분명히 됐는데?!"의 범인 중 하나는 대개 로컬 환경과 배포 환경의 프로토콜(http vs https) 차이로 인한 Redirect URI 불일치다.