OAuth2.0이란?
OAuth란?
RESTAPI가 서로 다른 두 애플리케이션 간 데이터를 간편하게 전달하기 위해 만든 관례라면, OAuth는 데이터를 간편하고 안전하게 주고받기 위해 만들어진 표준입니다.
OAuth는 ID와 비밀번호 대신 액세스 토큰(Access Token)을 기반으로 사용자를 식별합니다. 이 토큰은 API를 제공하는 리소스 서버만 발급할 수 있으며 일정시간(대부분 1시간)이 지나면 폐기될 수 있습니다. 또한 모든 토큰은 필요한 권한만 지니게 할 수 있어서 OAuth를 이용하면 서버는 클라이언트의 접근 권한을 쉽게 제어할 수 있다는 장점이 있습니다.
OAuth의 장점
OAuth를 사용할때의 장점을 페이스북 API를 사용하는 앱을 예시로 들어 설명하겠습니다.
- 페이스북 API를 사용할 때 읽기 권한만 가진 액세스 토큰을 만들 수 있습니다. 앱이 페이스북 인증을 지원하고 읽기 전용 토큰만 사용한다면 이 앱은 토큰으로 페이스북 글을 게시할 수 없습니다.
- 페이스북 인증을 사용하는 모바일 앱은 사용자의 ID와 비밀번호가 필요하지 않습니다. 사용자는 페이스북 페이지에서 로그인하면 페이스북은 모바일 앱에 사용자가 승인한 권한만 있는 액세스 토큰을 전달하기 때문입니다.
- API를 사용하는 모바일 앱이 해킹당해도 권한 도용으로 인한 손실을 최소화할 수 있습니다.
- 필요에 따라서는 액세스 토큰을 즉각 폐기 처리할 수 있습니다.
- 플랫폼에 상관 없이 API의 접근 제한을 쉽게 할 수 있습니다.
OAuth 1.0 VS OAuth 2.0
현재 OAuth 표준은 1.0a와 2.0 두 가지 버전이 있습니다. 그러나 1.0a와 2.0은 이름만 같을 뿐 동작 방식이 다릅니다. 이 글에서는 1.0a의 동작 구조를 자세하게 다루지 않고 2.0 버전과의 차이점만 간락하게 설명하겠습니다.
OAuth 1.0a는 API를 사용하는 클라이언트가 필요한 권한을 갖고 있는지 확인하며, 액세스 토큰을 획득한 방법까지 알 수 있기 때문에 인증(자신을 증명하는 일)과 인가(권한을 확인하는 일) 역할을 모두 수행합니다. 그래서 2.0보다 더 안전하다고 볼 수 있습니다.
하지만 OAuth2.0에 비해 인증 과정이 복잡하고 표준에서 요구하는 서명(signature), 요청 토큰(request token)등 여러 보안 요소들을 직접 구현해야 해서 별도의 라이브러리가 있더라도 직접 구현하는데 꽤 오랜 시간이 필요하다는 단점이 있습니다.
OAuth2.0은 1.0a에 있는 인증 절차가 삭제되고, 인가 절차만 남아 1.0a보다 구조가 간단하며 사용하기 쉽습니다. 그러나 권한을 확인하는 데 사용할 액세스 토큰을 어떻게 얻는지 확인할 방법이 없어서 가로채기 형태의 공격에 취약합니다.(Hijacking)
OAuth 2.0에서 제거된 인증 기능을 보완하는 건 전적으로 개발자에게 달렸습니다. 따라서 개발자는 인증 기능을 보완할 방법 중 하나로 HTTPS 위에서 OAuth2.0을 사용하는 방식을 채택할 수도 있습니다. HTTPS를 사용하면 메시지가 암호화 되므로 가로채기 공격을 막을 수 있습니다.(관련하여 자세한 내용은 HTTPS 관련 포스팅을 참고해주세요)
그러나 상황에 따라 엑세스 토큰 만료 시간을 분 단위로 줄이거나 액세스 토큰을 발급한 IP만 토큰 사용이 가능하게 만드는 등의 더욱 강력한 보안 정책이 필요할 수도 있습니다.
Access Token
액세스 토큰은 어플리케이션이 API에 액세스할 수 있도록 토큰 기반의 인증에 사용됩니다.
어플리케이션은 사용자가 성공적으로 액세스를 인증하고 승인한 후에 액세스 토큰을 수신한 다음 타겟API를 호출할 때 엑서스 토큰을 자격 증명(credential)으로 전달합니다.
전달된 토큰은 토큰의 베어러(Bearer)가 API에 액세스하고 권한 부여 중에 부여된 권한 범위에 의해
허가된 특정 작업을 수행할 수 있는 권한이 있음을 API에 알립니다. (Access Token에 관련하여 자세한 내용은 참고 자료란에 링크를 참고해주세요)
OAuth 프로토콜은 어떻게 작동하는 걸까?
OAuth 2.0이 어떻게 동작하는지에 대해 알아보기에 앞서 위 그림을 통해 동작 방식 이해에 필요한 용어부터 알아보겠습니다.
리소스 소유자
리소스 소유자는 리소스 서버에서 제공하는 기능을 실제로 사용할 주체이자, ID와 비밀번호를 이용해 리소스 클라이언트에게 권한을 인가하여 액세스 토큰을 획득하게 될 주체입니다.
대부분 리소스 소유자는 사람이기 때문에 최종 사용자(end-user)라고도 합니다. 상황에 따라 클라이언트나 백엔드 서버와 같은 컴퓨터도 주체가 될 수 있습니다.
리소스 클라이언트
리소스 클라이언트는 리소스 소유자로부터 사용 인가를 받아, 소유자 대신 액세스 토큰을 획득하며 액세스 토큰을 사용해 리소스 서버의 API를 사용하는 주체입니다.
페이스북이나 구글 인증 또는 카카오 인증 기능을 사용하는 다양한 모바일 앱, 웹 서비스가 리소스 클라이언트에 해당합니다.리소스 클라이언트는 스스로 리소스를 다룰 수 없기 때문에 소유자, 즉 최종 사용자의 인가가 반드시 필요합니다.
인가 서버
인가 서버는 액세스 토큰과 인가 코드를 관리하는 서버입니다. 리소스 서버가 올바른 액세스 토큰을 받았는지 검증하기도 하며, 만료된 액세스 토큰을 폐기하기도 합니다. 리소스 클라이언트의 요청을 제어하기 위해 리소스 클라이언트의 권한을 제어할 클라이언트ID와시크릿 정보를 관리합니다.
💁🏻♂️ 실무에서 인가 서버는 인증 기능을 겸하는 경우도 많아 인증 서버라 부르기도 합니다. 하지만 OAuth2.0에서는 인가 서버로 보는게 맞습니다.
리소스 서버
리소스 서버는 보호된 리소스를 관리하며 리소스 클라이언트가 사용할 API를 제공하는 주체입니다.
API를 사용하기 위해서는 액세스 토큰이 필요하며, 리소스 서버는 액세스 토큰이 유효한지 확인하기 위해 인가 서버와 통신을 주고 받기도 합니다.
💁🏻♂️ API를 사용할 때마다 토큰의 유효성을 확인하면 인가 서버의 부하가 커져 비효율적인 구조가 됩니다. 이를 보완하기 위해 인가 내역을 캐싱하거나, 토큰 자체에 인가 내역을 확인할 수 있는 형태인 JWT를 사용하기도 합니다.(JWT에 대해서는 추후 다른 포스팅으로 설명할 예정입니다)
OAuth 2.0.의 동작 방식
동작 구조를 이해하기 위해 필요한 용어들을 살펴봤으니 이어서 인가 절차를 자세히 설명하겠습니다. 설명을 위해 페이스북 로그인이 가능한 앱을 예를 들어 설명하겠습니다.
페이스북 로그인이 가능한 앱은 리소스 클라이언트로 볼 수 있고, 앱을 사용하는 사용자가 리소스 소유자가 됩니다. 인가 서버와 리소스 서버는 페이스북이라 가정하겠습니다.
인가 요청 및 로그인
- 사용자는 페이스북 앱을 실행하고, [가입하기] 버튼을 클릭할 것입니다.
- [가입하기] 버튼을 클릭하는 순간, 페이스북 앱은 페이스북 페이지를 열어 권한 인가를 요청합니다. 페이스북으로 가입하기 기능을 사용해봤다면 아래와 같은 화면이 익숙하실 겁니다.
위에 그림과 같은 화면이 인가 요청 화면 입니다.
인가 코드 획득 및 액세스 토큰 요청
사용자가 페이스북으로 가입하기에 대한 인가 과정을 완료하고 나면, 페이스북 회사에 있는 인가 서버는 인가를 요청했던 앱으로 인가 코드를 전달합니다. 이때 페이스북 공식 소프트웨어 개발 키트(SDK)를 사용하면 인가 코드 없이 액세스 토큰을 바로 획득할 수도 있습니다. 만약 인가 코드를 받은 경우, 앱은 인가 코드를 다시 액세스 토큰으로 변환하는 작업이 필요합니다.
액세스 토큰을 받은 앱은 액세스토큰이 적절한 권한이 있는지 확인하는 작업을 진행하기도 합니다.
페이스북을 포함한 대부분 OAuth 기반 API는 액세스 토큰의 권한을 확인하는 기능을 제공합니다.
보호된 리소스 요청
앱은 사용자의 액세스 토큰을 사용하여 페이스북 API를 사용할 수 있습니다. ‘페이스북 가입하기’ 기능은 유저 ID를 필요로 하니, 앱은 페이스북 API로 유저 ID를 가져오는 작업을 수행할 것입니다.
페이스북 ID는 플랫폼마다 고유하기 때문에 다음과 같은 조합을 사용하면 중복되지 않은 고유한 ID를 확보할 수 있습니다. 페이스북의 경우, 다음과 같은 ID를 만들 수 있습니다.
facebook102133134413087554
페이스북으로 가입하기 기능 테스트
실무에서 ‘페이스북 가입하기’ 기능을 만든다면 페이스북이 제공하는 그래프 API 탐색기 기능을 사용해 액세스 토큰을 어떻게 사용하는지, 페이스북 ID를 어떻게 가져오는지 테스트할 수 있습니다.
그러나 이런 그래프 API 탐색기 같은 기능은 페이스북처럼 규모가 큰 회사가 아닌 이상 해당 기능이 없을 수도 있습니다. 그럴 때 우리는 포스트맨과 같은 테스트 도구를 사용해 직접 API를 호출하면서 사용법을 익혀야 합니다.
참고 자료
'프로그래밍 > HTTP' 카테고리의 다른 글
HTTP 1.0 VS 1.1 vs 2.0 vs 3.0 (0) | 2022.11.20 |
---|