[RFC 6749] #02. Introduction

undefcat·2020년 3월 22일
2

RFC 6749

목록 보기
2/5
post-thumbnail

Introduction

어떤 어플리케이션이든 인증(Authentication)은 매우 중요하다. 모든 어플리케이션의 시작점은 바로 인증이다.

요즘 세상은 매우 다양한 인증 방식이 보편화 되어있다. SNS로그인등이 대표적인데, 신뢰할 수 있는 서비스의 계정정보를 이용하여 자체 서비스에 활용하는 방식은 이젠 새롭지도 않다.

오히려 이제는 SNS로그인이 없으면 불편하기까지 하다. 고객의 입장에서는 새로운 서비스에 가입할 때마다 매번 계정정보를 입력하는게 귀찮고, 요즘 같은 시대엔 사용하는 서비스도 많아 각 서비스마다 계정 정보를 외우기가 피곤하기 때문이다.

많은 사람들이 SNS로그인 기능을 사용해봤으므로, 대략 어떤 식으로 인증이 이루어지는지는 잘 알고 있을 것이다.

SNS로그인이 보통 어떻게 이루어지는지 보자.

  1. A에 접속한다.
  2. SNS로그인 버튼(이 서비스를 B라고 하자)을 클릭한다.
  3. B로 리다이렉트 된다(혹은 팝업이 뜬다).
  4. B에서 로그인 한다.
  5. 로그인 이후 다시 A로 리다이렉트 된다(혹은 팝업이 닫힌다).
  6. B정보를 A에서 이용할 수 있다.

사용자 입장에서는 생각보다 편리하게 이용할 수 있다. 그러나 이런 편리함 뒤에는 많은 것들이 숨겨져있기 마련이다.

앞으로 RFC 6749 문서를 통해 우리(개발자)가 알아야 할 것, 해야할 것이 무엇인지 공부하면서 실제로 구현해볼 것이다.

등장배경

OAuth 2.0과 같은 스펙이 등장한 이유는, 전통적인 클라이언트-서버 인증방식에 한계점이 있기 때문이다.

전통적인 클라이언트-서버 방식에서는, 클라이언트에서 서버로 인증정보를 전송하면 서버에서 이를 확인하고 인증하는 방식이다. 이 사이에는 오직 고객-서비스, 이 두 계층만이 존재했다.

그런데 시간이 지나 SNS가 등장하게 되고, SNS는 특성상 사적인 정보가 많이 포함되어 있으므로 이를 다른 서비스에서 활용할 여지가 생겼다.

SNS 업체에서는 자사 서비스가 갖고 있는 고객의 정보를 다른 서비스에 활용할 수 있게 해주면(고객의 동의 하에)

  1. 다른 서비스가 자사 서비스에 의존적이게 되어 입지가 더 커질 것이고
  2. 고객 역시 이를 통해 더욱더 자사 서비스에 의존적이게 될 것이므로(예를 들어 많은 서비스에 페이스북 로그인을 통해서 회원가입을 하게 되면, 페이스북을 탈퇴하기가 더욱 힘들어 질 것이다)

이는 매우 좋은 서비스 전략이 될 수 있다.

마찬가지로 써드 파티 서비스(SNS를 이용하는 다른 서비스)의 경우, 대형SNS 기업의 고객 정보를 이용하면 해당 SNS에서 제공해주는 많은 기능을 통해 더욱더 좋은 서비스를 고객에게 제공할 수 있으므로 매우 좋은 전략이 될 수 있다.

고객의 입장에서도 가입이 편리하고 이미 사용하고 있던 정보를 다른 서비스에서도 활용할 수 있어 좋다.

물론 위에서는 SNS를 예시로 들었지만, 굳이 SNS가 아니더라도 다른 서비스들도 충분히 제공할 수 있다. (네이버, Github 등...)

이렇게 고객-서비스 사이에 새로운 계층이 끼어들게 되어, 전통적인 인증방식을 사용하게 된다면 문제가 발생하는데

  • 고객(Client, R과 T의 이용자): C
  • 정보제공 서비스(Resource, C의 정보를 갖고 있는 서비스업체): R
  • 써드파티(Third-party, R로부터 C의 정보를 이용하고자 하는 업체): T

이 3계층에서, T가 R을 통해 C의 정보를 얻고자 한다면

  • T는 C의 인증정보(R을 사용하기 위한)를 저장하고 있어야 한다.
    • 그래야 T가 R에서 C의 정보를 획득할 수 있다.
  • T는 C와 동등한 정보를 얻을 수 있다.
    • T는 C가 R을 이용하는 것과 같은 권한이 생기기 때문이다.
  • C가 더 이상 T를 사용하지 않는 경우, R의 인증정보를 바꿔야 한다.
    • T가 C의 인증정보를 저장하고 있기 때문에
  • C는 T가 자신의 인증정보를 가지고 어디에 서비스를 활용할 지 알 수 없다.

OAuth 2.0에서는 이렇게 C의 인증정보를 T가 저장하고 있는 것이 아닌, Access Token 개념을 이용하여 임시로 C의 정보를 활용할 수 있게 한다. 또한, 구현에 따라 Access Token에 정보의 제약을 걸어 T가 무한정 정보를 이용할 수 있는 것이 아닌 제한적인 정보만 허용하도록 권한을 부여할 수 있다.

Roles

OAuth 2.0에서는 다음과 같은 4개의 역할을 구분하고 있다.

resource owner

  • 정보의 소유자. 보통 서비스를 이용하는 사용자다.

resource server

  • resource owner의 정보가 있는 서버.
  • SNS나 네이버, 구글 등이 될 것이다.

client

  • 위에서 언급했던 써드파티 서비스가 이에 해당한다.

authorization server

  • Access Token을 발급하는 서버
  • 보통의 경우 resource server와 동일한 서버에 있는 경우가 많을 것이다.
  • 여러 resource serverAccess Token을 하나의 authorization server가 발급해줄 수 있다.

Protocol Flow

인증이 대략 어떻게 이루어지는지 살펴보자. 이는 Introduction에서도 언급했던 SNS로그인 과정이라고 볼 수 있다.

보통 ClientResource Owner에 대한 과정은 이루어 지지 않고, Resource Owner가 직접 Authorization Server와 인증을 거치고 그에 대한 Access TokenClient가 받게 되는 구조로 구현할 것이다.

Authorization Grant

다이어그램에서 ClientAccess Token을 얻기 위한 인증 권한을 획득하는 방법에는 4가지가 존재한다. 이 중 우리는 Authorization Code 방식과 Implict만을 알아볼 것이다. 나머지는 명세를 통해 확인하기 바란다.

Authorization Code

이 방식은 많은 서비스에서 이용되는 방식이다. Resource OwnerAuthorization Server에서 인증을 하고 나면, Authorization ServerResource OwnerClient로 리다이렉트 하면서 코드를 하나 발급해준다.

Client는 이 코드를 획득한 후, 다시 Authorization Server에 이 코드를 이용해서 Access TokenRefresh Token을 획득한다.

RFC 6749는 명세에서도 밝히듯, HTTP와 함께 사용되는 것을 전제로 작성되었다(This specification is designed for use with HTTP. - p.5). 물론 다른 프로토콜에서도 사용이 가능하긴 하다. 다만, 명세 자체는 HTTP를 사용하는 방식으로 설명되어있다.

즉, ClientResource Owner로부터 권한을 획득하는 과정을 Resource OwnerAuthorization Server와의 인증작업을 통해 그 결괏값을 Client에게 전달하는 방식이 기본이다.

이는 HTTP의 리다이렉션등의 기능을 통해 손쉽게 구현될 수 있다.

Implict

이 방식은 Authorization Code와 비슷하지만, 좀 더 간편한 방식이다. Resource OwnerAuthorization Server에서 인증을 처리한 후, 코드가 아닌 Access Token을 직접 Client에게 전달하는 방식이다. 이 방식의 장점은, Client가 바로 Access Token을 발급받아 사용할 수 있다는 장점이 있다.

Access Token

OAuth 2.0에서는 Access Token이 핵심이라고 볼 수 있는데, 여러 절차는 결국 ClientResource Server에서 사용할 수 있는 Access Token을 얻기 위한 과정이기 때문이다.

Access Token은 문자열이기만 하면, 세부 구현사항은 각 서비스의 몫이다. 단지 Access TokenResource Server가 이해할 수 있기만 하면 된다.

Access Token은 일종의 인증서라고 보면 된다. 이 토큰과 함께 Resource Server에 데이터를 달라고 하면, Resource Server는 토큰을 검증한 후 데이터를 전달해준다.

Refresh Token

Refresh TokenAccess Token을 얻기 위한 토큰이다. 이 Refresh Token의 목적 및 필요성에 대해서는 의견이 분분한 편이다.

명세에서는 Refresh Token의 정확한 필요성에 대해 언급하진 않았다.

단지 Access Token의 수명이 짧을 수 있고 Refresh Token을 이용해 최초의 Access Token보다 지엽적인 권한을 가진 새로운 Access Token을 발급 받을 수 있는 용도 정도로만 설명했고, Refresh Token의 발급은 Optional이라고 했기 때문에 이렇게 의견이 분분한 것 같다.

개인적으로 아직 경험이 부족하기 때문에, 이렇다 저렇다할 판단을 내리긴 힘든 것 같다. 다만 일단

  • Refresh tokens... mitigates the risk of a long-lived access_token leaking (query param in a log file on an insecure resource server, beta or poorly coded resource server app, JS SDK client on a non https site that puts the access_token in a cookie, etc)
  • revocation: if the access token is self contained, authorization can be revoked by not issuing new access tokens. A resource does not need to query the authorization server to see if the access token is valid.This simplifies access token validation and makes it easier to scale and support multiple authorization servers. There is a window of time when an access token is valid, but authorization is revoked.
  • refresh_token is only ever exchanged with authorization server whereas the access_token is exchanged with resource servers

위의 내용으로 숙지하고자 한다.

다음엔

다음엔 Client Registration 섹션과 시간이 된다면 Protocol Endpoints 섹션에 대해 정리해볼 것이다. (그럼 구현은 언제?😅)

profile
undefined cat

0개의 댓글