OAuth 2.0

권태형·2023년 5월 8일
0

지식정리

목록 보기
57/72
post-thumbnail

이번엔 카카오 로그인에 대한 구현을 해보기에 앞서 카카오로그인의 기반이되는 OAuth 2.0에 대해서 포스팅을 해보도록 하자.

일반적으로 전혀모르는 것에 대해서는 일단 공식문서가 있는지 없는지 찾아보게 되는데... 이게 참 한국 친화적이지 못한게 많다.

OAuth 2.0의 공식 페이지도 여간 보기 어려웠다.

대충 내게 필요한 내용에 대해서 뭐가 있을지, 정의라던가, 동작의 원리, 장단점, 만들어진 이유 등등 만을 찾아보려 해도 일일이 번역해가며, 구글 번역기에서 직역에 의한 답답한 내용을 또 어떻게 다시 한국어로 의역할 것인지 알아보는 것과, 너무 많은 양의 정보에 대해 어떻게 축약해야 할지 생각하는게 참 어려웠던 것 같다.

위 그림을 보면 OAuth 2.0 framwork 라는 가장 첫번째 목차를 볼 수 있다.

😀아 OAuth 2.0은 프레임워크 구나! 그리고 카카오 로그인과 같은 소셜 로그인서비스는 이 프레임워크를 이용해서 회원인증 로직을 구현했기 때문에 OAuth 2.0을 기반으로 만든 소셜 로그인 서비스 라고 하는구나! 그럼 누구나 다 쓰는 큰 대형 플래폼이 된다면, 위 프레임워크를 이용해 자사 소셜 로그인서비스를 구현할 수도 있겠구나! 라는 생각이 들었다.

그럼 이제 좀 더 OAuth 2.0에 대해서 알아보자. OAuth 2.0 framwork에 step-in해서 들어가면 간단한 요약정보과 저작권관련 내용을 말해주고, 굉장히 많은 정보를 보여주는 목차를 보여준다. 영어 원문으로 작성된 해당사이트 기준 페이지로 75페이지에 이르는 방대한 내용, 여기서 나는 이 포스팅에 필요하다 생각되는 부분은 골라서 볼 것이다.


Oauth 2.0란?

The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
behalf of a resource owner by orchestrating an approval interaction
between the resource owner and the HTTP service, or by allowing the
third-party application to obtain access on its own behalf.

공식문서의 요약
OAuth 2.0는 권한 부여 프레임워크로 제 3자 애플리케이션이 HTTP 서비스에 대한 제한적인 액세스를 리소스 소유자의 승인 상호작용을 조율하거나, 제 3자 애플리케이션이 자체적으로 액세스를 얻을 수 있도록 허용함으로써 리소스 소유자 대신 HTTP 서비스에 접근할 수 있도록 한다.

⛔하지만 많은 포스팅에서 Oauth 2.0은 프로토콜이라고 설명한다. 공식문서에서는 OAuth 2.0이 프로토콜 뿐만 아니라, 여러 구성요소와 상호작용 방식, 프로세스 등을 포함하는 광범위한 개념을 가지고 있기 때문에 프레임 워크라고 설명한다. OAuth 2.0 자체로는 개발을 위한 구조화된 환경을 제공하지 않지만, OAuth 2.0은 여러 인증 및 권한 부여 시나리오를 위한 기본적인 규칙과 프로토콜을 제공하며, 개발자들은 이를 기반으로 자신들의 애플리케이션에서 권한 부여 기능을 구현할 수 있다. 그러한 의미해서 이 공식문서에서는 프레임워크라는 표현을 사용하는 것 같다.

우리가 생각하는 Oauth 2.0의 정의
구글, 페이스북, 트위터와 같은 다양한 플랫폼의 특정한 사용자 데이터에 접근하기 위해 제3자 클라이언트(우리의 서비스)가 사용자의 접근 권한을 위임(Delegated Authorization)받을 수 있는 개방형 표준 프로토콜이다.


등장배경

In the traditional client-server authentication model, the client
requests an access-restricted resource (protected resource) on the
server by authenticating with the server using the resource owner's
credentials....

전통적인 클라이언트-서버 인증 모델에서 클라이언트는 자원 소유자의 자격 증명을 사용하여 서버에서 액세스 제한된 자원(보호 자원)에 대한 액세스를 요청한다. 제한된 자원에 대한 제3자 응용 프로그램의 액세스를 제공하기 위해 자원 소유자는 제3자와 자격 증명을 공유한다. 이는 아래와 같은 몇 가지 문제와 제한 사항을 만들 수 있다.

  • 제3자 응용 프로그램은 일반적으로 암호화되지 않은 비밀번호와 같은 자원 소유자의 자격 증명을 미래의 사용을 위해 저장해야한다.
  • 서버는 비밀번호에 내재된 보안 취약점에도 불구하고 비밀번호 인증을 지원해야한다.
  • 제3자 응용 프로그램은 자원 소유자의 보호 된 자원에 대해 지나치게 넓은 액세스 권한을 얻어 자원 소유자가 자원의 지속 시간이나 제한된 자원 하위 집합에 대한 액세스를 제한할 수있는 능력이 없다.
  • 자원 소유자는 개별적인 제3자의 액세스를 철회할 수 없으며, 이는 모든 제3자의 액세스를 철회함을 의미하며, 이를 위해 제3자의 비밀번호를 변경해야한다.
  • 제3자 응용 프로그램의 어떤 침해도 최종 사용자의 비밀번호와 해당 비밀번호로 보호 된 모든 데이터의 침해로 이어질 수 있다.

위와 같은 문제와 제한사항을 해결해 주기위해 만들어진 OAuth이다. OAuth는 인가 계층을 도입하고 클라이언트의 역할을 자원 소유자와 분리함으로써 이러한 문제를 해결한다. OAuth에서 클라이언트는 자원 소유자가 제어하고 리소스 서버에서 호스팅되는 자원에 대한 액세스를 요청하고 자원 소유자의 자격 증명과 다른 집합의 자격 증명이 발급된다.


프로토콜의 흐름

프로토콜의 흐름에 앞서 해당 흐름을 이해하기 위한 키워드에 대해 알아보자.

명칭설명
Resource Owner리소스 소유자 또는 사용자. 보호된 자원에 접근할 수 있는 자격을 부여해 주는 주체.
OAuth2 프로토콜 흐름에서 클라이언트를 인증(Authorize)하는 역할을 수행한다.
인증이 완료되면 권한 획득 자격(Authorization Grant)을 클라이언트에게 부여한다.
개념적으로는 리소스 소유자가 자격을 부여하는 것이지만 일반적으로
권한 서버가 리소스 소유자와 클라이언트 사이에서 중개 역할을 수행하게 된다.
Client보호된 자원을 사용하려고 접근 요청을 하는 애플리케이션이다.
Resource Server사용자의 보호된 자원을 호스팅하는 서버이다.
Authorization Server권한 서버. 인증/인가를 수행하는 서버로 클라이언트의 접근 자격을 확인하고
Access Token을 발급하여 권한을 부여하는 역할을 수행한다.

공식문서에서 프로토콜의 흐름

공식문서에는 다음과 같이 설명하고 있다.

  • A. 클라이언트는 리소스 소유자에게 권한을 요청한다. 권한 요청은 리소스 소유자에게 직접적으로 요청할 수 있습니다(그림에서와 같이), 또는 중개자로서의 인증 서버를 통해 간접적으로 요청할 수 있다.

    B. 클라이언트는 권한 부여를 받는다. 권한 부여는 이 명세서에서 정의된 네 가지 부여 유형 또는 확장 부여 유형 중 하나를 사용하여 표현되는 리소스 소유자의 권한을 나타내는 자격 증명이다. 권한 부여 유형은 클라이언트가 권한을 요청하는 방법과 인증 서버가 지원하는 유형에 따라 달라진다.

    C. 클라이언트는 인증 서버와 인증하고 권한 부여를 제시함으로써 액세스 토큰을 요청한다.

    D. 인증 서버는 클라이언트를 인증하고 권한 부여를 검증하고 유효하면 액세스 토큰을 발급한다.

    E. 클라이언트는 액세스 토큰을 제시하여 리소스 서버에서 보호된 리소스를 요청하고 인증한다.

    F. 리소스 서버는 액세스 토큰을 검증하고 유효하면 요청을 처리한다.

클라이언트가 리소스 소유자로부터 권한 부여를 받는 우선적인 방법(단계 (A) 및 (B)에 나타남)은 중개자로서의 인증 서버를 사용하는 것이다.

😀처음에는 도저히 이해가 안갔다. 이게 말이야 방구야 뭐야! 클라이언트가 리소스 소유자에게 권한을 요청한다? 사용자가 사이트에 접속하기 위해서 클라이언트에 요청을 하면 서버로 요청을 보내는 형식이 아니라, 클라이언트가 먼저 사용자에게 보낸다니? 그게 말이되는 걸까? 만약 내가 아무런 요청도 안했는데 사이트에서 나한테 막 요청을 보낸다고? 머리속에 의문이 오래남았고, 해답을 찾아 고민하는 시간이 오래걸렸다.

위 흐름에 대한 예시

예를 들어보자!
K라는 사용자가 T라는 사이트에 H소셜로그인을 진행한다고 생각하자.

  1. 사용자 K가 사이트T에 H소셜로그인 버튼을 클릭하여 소셜로그인 요청을 먼저 보낸다.
    위의 과정에서 생략된 이 한부분이 내 삽질하는 시간을 많이 잡아먹었다.

  2. 사이트T의 클라이언트가 사용자 K에게 H소셜로그인 창을 보여주며 사용자에게 로그인 정보를 요청한다.
    여기서부터 위 프로토콜의 흐름의 시작 A항목이라고 볼 수 있다.

  3. 사용자는 로그인창에 ID와 password를 입력하고 H소셜로그인 필수 체크항목 등의 권한을 작성해서 T클라이언트에 요청을 보낸다.

  4. 사이트T의 클라이언트는 사용자에게 받는 정보를 가지고 H소셜로그인 서버에 요청을 보낸다.

  5. H소셜로그인 서버에서 해당 정보를 검증하고, Access Token을 사이트T의 클라이언트에 보낸다.

  6. 사이트T의 클라이언트는 받는 Access Token으로 사이트T의 메인 서버에 로그인 요청을 보내면.

  7. 사이트T의 메인 서버에서 클라이언트 측으로 로그인 성공메시지를 보내준다.

😀위의 과정을 예시를 들어 표현해보니 조금 알 것 같았다. 하지만 또 이해되지 않는 부분이 또 존재했다. H소셜로그인 서버에서 보내준 AccessToken을 받아도 사이트T에서는 검증할 방법이 없지 않나? 만약 로그인 된 사용자만 사용할 수 있는 기능이라면, 해당 AccessToken을 검증해야할텐데, 사이트T의 서버는 H소셜로그인 서버의 secretkey를 알지 못하기에 검증할 수 없을 것이다.

이러한 의문점에 대해서 정답은 카카오 로그인 설정탭의 설명을 보고 해소되었다.

결국 6번과 7번 과정 사이에 사이트T의 메인서버는 해당 AccessToken으로 다시한번 H소셜로그인서버에 회원 정보를 요청하고, 해당정보를 받아서 자체 데이터베이스에 회원가입처리를 하고 로그인성공 메시지와 함께 사이트T만의 다른 AccessToken을 발급해주고, 이를 통해서 사이트T 내의 요청에 대한 토큰 검증을 진행할 수 있을 것이다.

😀쉽게 생각하면 로그인이 2번 진행된다고 생각해볼 수도 있겠다. 아무래도 토큰의 발급은 로그인진행이 완료될 때 발급되는데, 위 과정에서는 토큰을 두번 발급하기 때문이다.

만약 카카오라면, 카카오로그인을 통해 AccessToken을 발급받는데, 그 AccessToken으로 해당 사이트에서는 카카오에 다시 요청을 보내 정보를 얻고, 자사의 데이터과 비교한 후 자사의 AccessToken을 발급하는 로그인과정을 한번 더 거치게 된다고 볼 수 있다.

23-05-09추가😀 소셜로그인에서 발급한 AccessToken을 검증하는 방법을 찾기는 찾았다. 위 과정에서 소셜로그인의 AccessToken을 이용하여 회원정보를 요청하여 받아오는 구간이 있는데, 이 부분에서 우리가 AccessToken을 전달하게되면, 소셜로그인 측 인증서버에서 회원정보를 가지고 오기전에 해당 AccessToken을 내부적으로 검증하고 사이트T에 회원정보를 넘기게 된다. 따라서 사이트T는 이 회원정보요청 과정을 통해 AccessToken이 만료가 되었는지 안되었는지 간접적으로 확인할 수 있다. 이 과정이 조금 야매스럽기는 하지만, 분명 가능한 방법이기는 하다.


참고자료(출처)
네이버블로그 MDS인텔리전스 OAuth 2.0 동작 방식의 이해
OAuth 2.0 공식문서
KAKAO developers

profile
22년 12월 개발을 시작한 신입 개발자 ‘권태형’입니다. 포스팅 하나하나 내가 다시보기 위해 쓰는 것이지만, 다른 분들에게도 도움이 되었으면 좋겠습니다. 💯컬러폰트가 잘 안보이실 경우 🌙다크모드를 이용해주세요.😀 지적과 참견은 언제나 환영합니다. 많은 댓글 부탁드립니다.

0개의 댓글