#OpenID,  #OAuth2.0

OpenID와 OAuth2.0

OpenID와 OAuth2.0

요즘 많은 서비스가 소셜 로그인을 지원합니다. 저만 해도 새로운 서비스를 이용할 때, 네이버 또는 카카오 로그인이 있으면 거기에 손이 먼저 가는데요. 번거로운 개인 정보 입력을 생략할 수 있는 소셜 로그인은 사용자 입장에서 참 고맙습니다. 개발자 입장에서도 신규 유저들의 가입 장벽을 낮추고, 인증/인가를 대신 처리해주니 정말 좋죠.
이번 우테코 4기 레벨3 프로젝트에도 거의 모든 팀이 소셜 로그인을 적용했는데요, 제가 속한 줍줍 팀도 Slack 소셜 로그인을 도입했습니다.
그런데 SlackOAuth2.0OpenID Connect를 이용한 두 가지 로그인 방식을 제공하고 있어서, 둘 중 하나를 선택해야 했습니다. 여러분은 이 둘의 차이를 아시나요?

OAuth2.0와 OpenID Connect

이 둘을 완벽하게 분리해서 얘기하기는 힘듭니다. OpenIDOAuth 프로토콜 위에서 동작하기 떄문이죠. HTTP 통신이 소켓 통신 위에서 동작하는 것과 유사합니다. 아직 OAuth가 생소한 분들은 같은 테코블의 글 OAuth 개념 및 동작 방식 이해하기를 먼저 읽으시는 걸 추천합니다.

OpenID를 관리하는 비영리 재단인 OpenID Foundation에서 직접 정의한 OpenID의 개념은 다음과 같습니다.

OpenID Connect 1.0은 OAuth 2.0 프로토콜 위에서 동작하는 간단한 ID 레이어입니다. 이를 통해 클라이언트는 인증 서버에서 수행한 인증을 기반으로 최종 사용자의 신원을 확인할 수 있을 뿐만 아니라, 최종 사용자에 대한 기본 프로필 정보를 상호 운용 가능하며 REST와 유사한 방식으로 얻을 수 있습니다. OpenID Connect를 사용하면 웹 기반, 모바일, 자바스크립트 클라이언트 등을 포함한 모든 유형의 클라이언트에서 인증 세션과 최종 사용자에 대한 정보를 요청하고 받을 수 있습니다. 스펙은 확장 가능하므로 필요에 따라 참가자들에게 ID 데이터 암호화, OpenID 제공자 확인, 로그아웃 등을 이용할 수 있습니다.

최종 사용자, 인증 서버등 생소한 용어가 보이네요. 더 쉬운 이해를 위해 OpenID가 동작하는 과정을 예시로 간단히 살펴보겠습니다.

openid
  1. 최종 사용자(서비스 유저)가 소셜 로그인 버튼을 클릭합니다.
  2. 웹사이트나 앱 등이 클라이언트로써 OpenID 제공자에 ID tokenaccess token을 요청합니다.
  3. OpenID 제공자는 승인 페이지에서 최종 사용자의 승인을 요청합니다.
  4. 최종 사용자는 승인 버튼을 눌러 허가합니다.
  5. OpenID 제공자는 일회용 인증 코드(Authorization code)를 클라이언트에 발급합니다.
  6. 클라이언트는 발급받은 인증 코드와 클라이언트 정보로 ID tokenaccess token을 다시 요청합니다. 이 떄 클라이언트 정보는 Client IDClient secret을 의미합니다.
  7. OpenID 제공자는 ID tokenaccess token을 클라이언트에 발급합니다.
  8. 클라이언트는 access token으로 자원 서버에 필요한 자원을 요청합니다.

OAuth절차를 이미 알고 계시다면 차이점이 없다고 생각하실 수 있습니다. 사실 절차상 보이는 차이점은 access token과 함께 하이라이트 된 ID token을 추가 요청/발급한다는 것 밖에 없습니다. OAuth 위에서 동작한다는 의미가 이제 명확히 보이시나요?

OpenID의 차별점

OpenID Connect는 어떤 차별점을 추가해 사용자에게 어필하고 있을까요?

  1. 스코프(Scopes): OpenID Connect의 변경 사항 중 가장 핵심적인 부분입니다. OAuth 2.0애서 제공자가 원하는 대로 요청 범위를 설정할 수 있었습니다. 이는 유연한 사용이 가능했지만, 상호 운용을 거의 완벽히 불가능하게 만들었습니다. OpenID Connect는 이 요청 범위를 openid, 프로필, 이메일, 주소로 표준화했습니다.
  2. 클레임: 요청 범위를 표준화 한 것에 더해, OpenID Connet는 요청 범위에 속하는 클레임의 종류도 표준화 했습니다. 사용자의 특정 정보와 인증의 세트가 이에 속합니다. 예를 들어 given_namefamily_name이라는 이름의 클레임을 지정한다면, 외부의 다른 시스템에서 반복과 예측 가능한 형식으로 사용자 정보를 받을 수 있습니다.
  3. ID token
    OpenID Connect에서 스코프는 특정한 정보 세트를 요청하는데 사용가능합니다. 이 정보는 클레임 값들로 만들 수 있습니다. ID token의 ID 정보는 상호 운용성에 중점을 둡니다. ID token을 통해 서드 파티 어플리케이션이 여러 웹 어플리케이션에 대해 동일한 인증 정보를 제공받을 수 있습니다.
    ID tokenJWT로 생성됩니다.
  4. 사용자 정보 요청 엔드포인트 통일
    ID token에 이어, OpenID Connect 구현을 통해 표준화된 엔드포인트를 제공합니다. 예를 들어 엔드포인트 중 /userinfo를 통해 사용자 메타데이터 정보를 검증할 수 있습니다. OpenID Connect는 엔드포인트 통일로 상호 운용성을 보장하기에 엔터프라이즈급 솔루션에 적합합니다. 상기한 차별점들을 종합해 볼 때, 결국 OpenIDOAuth 스펙을 통일해 클라이언트간의 상호 운용성을 보장하는 것을 최우선 가치로 둠을 알 수 있습니다.

무엇을 선택할까?

사실 일반 OAuth2.0와 확장된 OpenID Connect 중 무엇을 선택할지, 웹 개발자 입장에서 기술 본연의 특성을 놓고 논의할 일은 적다고 생각합니다. OAuth 제공사가 각자의 이유로 제공하는 것에 따를 수 밖에 없으니까요. 저희는 서비스 이용자의 특성을 고려해 적절한 제공사를 고르는 것이 더 중요하게 보입니다. 예를 들어 개발자를 위한 서비스라면 GitHub 로그인이 우선시 될 것 같습니다. 아쉽게도 GitHubOpenID를 지원하지 않아서, 일반 OAuth를 사용할 수 밖에 없겠네요. 반면, Google 로그인은 OpenID가 적용된 OAuth가 기본 사양이니 OpenID를 쓰지 않을 수가 없습니다.

잘 쓰이는 다른 소셜 로그인도 살펴볼까요? 카카오 로그인은 OAuth를 기본으로, 선택에 따라 OpenID를 활성화 할 수 있습니다! 카카오 로그인을 쓴다면 이제 개발 상황과 기술 특성을 놓고 얘기할 수 있겠네요. 저희가 프로젝트에 적용했던 Slack은 기본 OAuthOpenID를 둘 다 지원했지만, 기본 OAuth는 레거시 시스템으로 부르고 OpenID 사용을 권장하고 있었습니다. 하지만 OAuth 특징인 요청 스코프를 명확하게 보여준다는 것이, 사용자에게 더 신뢰를 줄 거라 생각해 OAuth를 채택했습니다.

이상으로 OpenID에 대해 알아봤는데요, 앞으로 소셜 로그인 방식을 두고 선택을 해야할 때 도움이 되었으면 좋겠습니다.

References