본문 바로가기
REST API

OAuth2.0

by 혀나Lee 2016. 9. 1.

OAuth와 OAuth2.0


OAuth는 3rd party(외부 서비스)를 위한 범용적인 인증 표준입니다.

외부 사이트와 인증기반의 데이터를 연동할 때 ID, Password를 넘기는 방법은 매우 위험합니다. ID, Password는 그 사용자의 모든 권한을 얻는 것이기 때문에 ID 도용 위험이 큽니다. 그래서 ID, Password를 사용자 임시 인증을 위한 Token을 제공하는 방식을 사용합니다. 그러나 이 방법이 각 서비스마다 제각각이어서 개발자들은 인증 연동을 각 서비스별로 따로 해야 했습니다. 그러다 보니 표준적인 방법이 필요했고, 그 표준 방법이 OAuth입니다.
- 출처: https://developers.daum.net/services/apis/docs/oauth2_0/intro


IT 기업에서 open API는 중요해지면서 어떠한 방식으로 API를 구성하고 데이터를 주고받을 것인지에 대해서도 논쟁이 많았다. SOAP & XML 과 REST & JSON의 논쟁 끝에 최근에 생기는 여러 API들은 REST & JSON의 기반으로 서비스를 제공하고 있으며 인증방식으로는 OAuth2.0을 사용하고 있다.

인증이란 REST API를 호출한 클라이언트가 적절한 사용자 인가를 판단해주는 것이다. 즉, API를 아무에게나 사용하도록 하는 것이 아니라 API를 호출할 수 있는 권한을 주고 클라이언트가 API를 호출할 때 권한이 있는지를 확인하는 것이 인증이다.

OAuth 용어

인증(Authentication)

  • 시스템 접근 시, 등록된 사용자인지 확인하는 것
  • 로그인

인가(Authorization)

  • 문서 읽기나 이메일 계정에 접근하는 등의 일부 행위를 수행할 권리를 가진 사용자를 검증하는 과정
  • 주로 권한을 검증하기 전에 사용자 인증을 요구함
  • 권한에 따라 사용 가능한 기능이 제한됨
  • 사용자 등급 (일반/관리자/슈퍼유저 등..)

권한 위임

  • 본인을 대신하여 다른 사람이나 애플리케이션에 권한을 부여
  • OAuth에서 사용자는 본인 대신 액션을 수행하도록 애플리케이션에게 접근을 허가하고, 애플리케이션을 허가받은 액션만 수행

역할

  • 자원 서버 (Resource Server): OAuth가 보호하는 사용자 소유의 자원을 호스팅하는 서버. 일반적으로 사진, 비디오, 주소록 같은 데이터를 보유하고 보호하는 API 제공 업체
  • 자원 소유자 (Resource Owner): 일반적으로 애플리케이션의 사용자. 
  • 클라이언트 (Client): 3rd 파티 애플리케이션
  • 인증 서버 (Authorization Server): 자원 서버에서 보호되는 자원에 접근하기 위해 자원 소유자에게 동의를 얻고 클라이언트에 액세스 토큰을 발행. (API 서버와 같을 수도 있음)

다양한 인증 방식 (Grant Types)

client는 기본적으로 Confidential Client와 Public Client로 나뉜다.
  • Confidential Client: 웹 서버가 API를 호출하는 경우 등과 같이 client 증명서(client_secret)를 안전하게 보관할 수 있는 Client를 의미한다. 
  • Public Client: 브라우저 기반 애플리케이션이나 모바일 애플리케이션 같이 client 증명서를 안전하게 보관할 수 없는 Client를 의미하는데 이런 경우, redirect_uri를 통해서 client를 인증한다

 

Confidential Client

Public Client 

 3-legged oAuth

Authorization code 

Implicit 

 2-legged oAuth

Resource Owner Password Credentials 

Client Credentials 


Oauth2.0이 지원하는 인증방식은 client 종류와 시나리오에 따라 아래 4가지의 종류가 있다. 하지만 실제 open API에서는 Authorization Code Grant와 Implicit Grant를 제외하고는 3-legged Oauth가 아니기 때문에 많이 사용되지 않는다.
(인증 방식에 따른 호출 방법 예시(Django-oauth-toolkit 사용): http://hyunalee.tistory.com/8)

1. Authorization Code

used with server-side Applications. 3-legged oAuth. 

웹 서버에서 API를 호출하는 등의 시나리오에서 Confidential Client가 사용하는 방식.

server side 코드가 필요한 인증 방식. 인증 과정에서 client_secret이 필요.

로그인시에 페이지 URL에 response_type=code라고 넘김.

2. Implicit

used with Mobile Apps or Web Applications (applications that run on the user's device). 3-legged oAuth

(token과 scope에 대한 스펙 등은 다르지만) oAuth1.0a와 가장 비슷한 인증 방식. Public Client가 사용하는 방식.

Client 증명서를 사용할 필요가 없으며 실제로 oAuth2.0에서 가장 많이 사용되는 방식.

로그인시에 페이지 URL에 response_type=token라고 넘김.

3. Resource Owner Password Credentials

used with trusted Applications, such as those owned by the service itself. 2-legged oAuth
Client에 아이디/패스워드를 저장해 놓고 아이디/패스워드로 직접 access token을 받아오는 방식.
신뢰할 수 없는 Client일 경우에는 위험성이 높기때문에, API 공식 애플리케이션이나 믿을 수 있는 Client에 한해서만 사용.
로그인시에 API에 POST로 grant_type=password라고 넘김.

4. Client Credentials

used with Applications API access. 2-legged oAuth
Confidential Client일 때 id와 secret을 가지고 인증하는 방식.
로그인시에 API에 POST로 grant_type=client_credentials라고 넘기.

Extension.

oAuth2.0은 추가적인 인증방식을 적용할 수 있는 길을 열어놓았으나 메인 에디터인 Eran Hammer는 이러한 과도한 확장성을 매우 싫어했다고 한다.

어떤 Grant Type을 사용해야 할까

grant란 access token을 얻기위한 방식이다. grant는 client 타입에 의해 결정된다.[각주:1]

https://alexbilbie.com/images/oauth-grants.svg


1st party or 3rd party client

1st party client: 사용자의 인증서를 다루기에 안전한 경우. (예, Spotify's iPhone app is owned and developed by Spotify so therefore they implicitly trust it.)

3rd party client: 신뢰할 수 없는 client.



다양한 토큰 지원(Access token)

OAuth 2.0은 기본적으로 Bearer 토큰, 즉 암호화하지 않은 그냥 토큰을 주고받는 것으로 인증을 한다. 기본적으로 HTTPS 를 사용하기 때문에 토큰을 안전하게 주고받는 것은 HTTPS의 암호화에 의존한다. 또한 복잡한 signature 등을 생성할 필요가 없기 때문에 curl이 API를 호출 할 때 간단하게 Header 에 아래와 같이 한 줄을 같이 보내므로서 API를 테스트해볼 수 있다.
Authorization: Bearer

또한 OAuth 2.0은 MAC 토큰과 SAML 형식의 토큰을 지원할 수 있지만 현재 MAC 토큰 스펙은 업데이트 되지 않아 기한 만료된 상태이고 SAML 토큰 형식도 아직은 활발하게 수정중이기 때문에 사용할 수 없는 상태이다. 정리하자면, OAuth 2.0은 다양한 토큰 타입을 지원한지만 실질적으로는 Bearer 토큰 타입만 지원한다.

Refresh token

클라이언트가 같은 access token을 오래 사용하면 결국은 해킹에 노출될 위험이 높아진다. 그래서 OAuth 2.0에서는 refresh token 이라는 개념을 도입했다. 즉, 인증 토큰(access token)의 만료기간을 가능한 짧게 하고 만료가 되면 refresh token으로 access token을 새로 갱신하는 방법이다. 이 방법은 개발자들 사이에서는 논란이 있는데, 토큰의 상태를 관리해야 해서 개발이 복잡해 질 뿐만 아니라 토큰이 만료되면 다시 로그인 하도록 하는 것이 보안 면에서도 안전하다는 의견이 있기 때문이다.

API 권한 제어 (scope)

OAuth 2.0은 써드파티 어플리케이션의 권한을 설정하기 위한 기능이다. scope의 이름이 스펙에 정의되어있지는 않으며 여러 개의 권한을 요청할 때에는 콤마등을 사용해서 로그인 시에 scope를 넘겨주게 된다.
http://example.com/oauth?….&scope=read_article,update_profile

  1. https://alexbilbie.com/guide-to-oauth-2-grants/ [본문으로]

'REST API' 카테고리의 다른 글

마이크로 서비스 아키텍쳐 (MSA)  (0) 2016.08.31
URI vs. URL (URI와 URL의 차이점)  (0) 2016.08.31
REST API란  (0) 2016.08.24

댓글