내가 제공하는 서비스(mine: opentutorials.org)가 다른 회사와 연동하거나 특정 정보 (혹은 서비스)를 이용하고 싶은 경우, 어떻게 그들의 회사 정보 (혹은 서비스)를 이용할 수 있을까?
이를 위해선, 우리(mine)가 사용자로부터 그 사용자가 사용하고 있는 벤더의 서비스에 접근할 수 있도록 허가를 받아야 한다. 이를 구현하는 가장 편리한 방법은, 우리(mine)가 사용자의 ID와 비밀번호를 기억하고 있다가 사용자의 정보를 통해 다른 벤더에 접근하는 것이다.
그러나 이것은
이 상황에서 OAuth를 이용하면 훨씬 안전하게 우리가 만든 서비스를 그들의 서비스와 활용할 수 있게 된다.
OAuth("Open Authorization")는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다. 이 매커니즘은 여러 기업들에 의해 사용되는데, 이를테면, 아마존, 구글, 페이스북, 마이크로소프트, 트위터가 있으며 사용자들이 타사 애플리케이션이나 웹사이트의 계정에 관한 정보를 공유할 수 있게 허용한다.
OAuth가 사용되기 전에는 인증방식의 표준이 없었기 때문에 기존의 기본인증인 아이디와 비밀번호를 사용했는데, 이는 보안상 취약한 구조일 가능성이 높다. 기본 인증이 아닌 경우에는 각 애플리케이션이 각자가 개발한 회사의 방법대로 사용자를 확인했다. OAuth는 이렇게 제각각인 인증방식을 표준화한 인증 방식이다. OAuth를 이용하면 이 인증을 공유하는 애플리케이션 끼리는 별도의 인증이 필요없다.
OAuth에 등장하는 3개의 주체를 살펴보자!
Client, ResourOwner, ResourServer 이 3자간의 관계가 OAuth에서는 핵심 개념이다. 이 개념을 명확히 이해하고 넘어가자.
opentutorials.org
): 우리가 만든 서비스OAuth 공식 매뉴얼에는 Authorization Server라고 하는 서버가 한개 더 있다. ResourceServer는 데이터를 가지고 있는 서버, Authorization server는 인증과 관련된 처리를 전담하는 서버다. 공식 메뉴얼에서는 이를 구분하지만, 우리는 이를 합쳐서 간략하게 살펴보자.
client가 ResourceServer를 이용하기 위해서는 ResourceServer에 승인을 사전에 받아놔야 한다. 이 과정을 등록이라고 한다. 등록 방법은 서비스마다 다른데, 공통적으로 Cliend Id, Client Secret, Authorized redirect URIs 이렇게 3가지 정보들을 공유한다.
새로운 App을 추가한다.
웹 사이트 주소를 입력한다.
사이트에 리다이렉트 주소를 입력한다. (유효한 주소가 아니다.)
App의 ID와 Secret이 생성된다.
등록을 하게 되면 Client와 Resource Server 양쪽 다 Client Id, Client Secret, redirect-URI를 알게 된다.
Resource Server가 제공하는 기능 A B C D가 있을 때, B, C 기능만 이용한다면 두 기능에 관해서만 인증을 받을 수 있다.
Resource Owner가 Client를 이용하던 중 Resource Server를 이용해야 할 상황이 있다면(페이스북 글 게시, 구글 캘린더에 날짜 기록), Resource Owner에게 아래 화면을 보여주거나, 귀하께서 하는 기능은 회사의 ~~기능이 필요한데, 이를 위해 인증을 거쳐야 합니다. 등의 동의를 구하는 창을 보여준다.
Resource Owner가 요청에 동의하면, Client는
https://resource.server/?client_id=1&scope=B,C&redirect_uri=https://client/callback
이라는 링크(주소)를 클라이언트에게 제공해주면 된다.
+) 실제 예시
Resource Owner가 Resource Server로 저 주소로 접속을 하게 되면, Resource Server가 Owner가 로그인이 되어있는지 확인하고, 로그인을 하라는 창을 보여준다.
Owner가 로그인에 성공하면, Resource Server는 그제서야
두 요소가 모두 일치하면, Resource Owner에게 Scope에 관한 권한을 Client에게 허용할 것인지 질문한다.
Owner가 권한 부여를 허용하면, userId와 scope(접근 가능한 서비스)을 db에 저장해둔다.
앞서 4번에서 Resource Owner의 승인을 받았다. 이제 Resource Server의 승인을 받아보자!
Resource Server는 바로 access token을 발급하지 않고, 한 단계를 더 거친다. 이때 사용하는 임시 비밀번호가 Authorization Code이다.
Resource Server는 Owner에게 Location
헤더로 Authorization code를 전송한다.
Location 헤더를 통해 리다이렉트 된 정보 https://client/callback?code=3
로 부터 Client는 authorization Code(여기서는 3)를 알게된다.
Client는 Resource Server에 직접 접근해 정보를 전달한다. Resource Servier는 Client로부터 전달받은 Authorization_code를 통해서 자신이 가지고 있는 정보(Client id, Client Secret, Redirect Id)와 일치하는지 확인한다.
앞서 Authorization_code를 기반으로 인증을 끝냈다. Resource Server는 다시 인증을 반복하지 않기 위해 Authorization_code 정보를 삭제해버린다. 그리고 드디에 Resource Server는 access token을 발급한다.
그리고 access token을 클라이언트에게 응답하는데, 클라이언트는 내부적으로 accessToken을 저장해둔다.
이제 Resource Server는 accessToken 4번으로 접근하면, userId가 1인 사용자에게 b, c가 유효함을 의미하는 access token이니까,
curl -H "Authorization: Bearer [TOKEN]" https://api.github.com/gists/starred
Authorization: Bearer
설정으로 토큰을 전송할 수 있다.