본문 바로가기
개발

클라이언트 입장에 포커스를 맞춘 OAuth 2.0 정리

by 상5c 2021. 6. 23.

이 글은 생활코딩 강의를 토대로 개인적으로 이해한 내용을 덧붙여 작성하였습니다.


사용자 sang5c가 구글에 가입되어있고, OAuth 인증을 통해 사용자의 정보를 프로그램 PGoogle에게서 얻어오는 과정을 예로 들어 설명합니다.

OAuth는 sang5cP에게 비밀번호를 제공하지 않고도 Google에 저장된 자신의 정보에 접근할 수 있는 권한을 부여할 수 있는 수단입니다. OAuth 인증이 완료되면 P에게 사용자의 토큰이 발급되며, 이 토큰을 사용하면 Google에 사용자를 대신하여 요청을 보낼 수 있습니다.
간단히 OAuth를 정리해보자면, OAuth는 사용자의 토큰을 얻기 위한 과정이다. 토큰이 있으면 사용자의 권한이 있다(API를 호출할 수 있다). 라고 할 수 있습니다.

용어 / 역할 정리

얻고싶은 자원인 사용자 sang5c의 정보를 Resource라 칭합니다. 사용자는 이 리소스의 주인이기 때문에 Resource Owner 입니다.
구글은 사용자의 정보를 저장하고 있으며, 사용자의 동의를 얻어 이 정보를 제공할 수 있습니다. 따라서 Resource Server라 호칭합니다. 이 글에선 설명의 편의를 위해 Authorization Server를 언급하지 않았으며, Resource Server와 동일하다고 가정하고 설명합니다.
프로그램 PResource Server에게 사용자의 정보를 요청하는 입장입니다. 따라서 Client라 호칭합니다.

 

사용자 -> Resource Owner

프로그램 P -> Client

Google -> Resource Server


1. 등록

Resource Server는 아무에게나 Resource를 제공해선 안됩니다. 미리 등록된 Client만 리소스를 사용 가능하도록 제한합니다.
리소스 서버를 사용하기 위해 사전에 승인 받는 과정을 등록(register)이라 부릅니다.

등록 과정에선 RedirectURI를 등록해야 합니다. 이 URI는 Client가 API를 정의한 URI이며, Resource Server에게서 Resource OwnerAccess Token을 얻는 작업이 이루어집니다. 이 작업은 잠시 뒤 설명합니다.

등록이 완료되면 ClientClient ID, Client Secret를 얻게 되며, 이는 Redirect URI와 함께 Resource Server에 저장됩니다.

2. OAuth 로그인

ClientResource Owner에게 Google ID로 로그인 버튼을 만들어서 제공해야 합니다.
이 버튼은 Resource Server에게 요청을 보내는 기능을 하며, 파라미터로 미리 발급받은 client id와 원하는 권한의 scope, redirect uri를 같이 전달 하도록 구성합니다.

사용자가 이 버튼을 누르면 구글로 연결되며, 로그인이 되어있지 않다면 로그인을 진행한 후 권한 위임에 대한 확인을 받습니다.

주목해야 하는 점은, 이 과정을 Client는 관여하지 않습니다. Resource OwnerResource Server가 과정을 진행합니다.
로그인이 이루어지고, 권한 위임에 대한 동의가 완료되면 Resource Server는 같이 전달한 Client IDRedirect URI를 확인합니다. 1번 과정에서 등록된 정보와 같다면 HTTP Response에 Location 헤더를 사용하여 사용자를 Redirect URI로 보냅니다. 리다이렉트시에 Authorization code를 함께 전달합니다.

  • HTTP/1.1 302 Found Location: / 이와 같은 HTTP Response를 받으면 Location에 명시된 주소로 사용자가 redirect 됩니다.

3. 토큰 획득

Client는 2번 과정을 통해 Authorization code를 획득하게 되었습니다. 이 Redirect URI 핸들러에서 Resource Server로 요청을 보내 사용자의 액세스 토큰을 얻는 로직을 구현해야 합니다.

액세스 토큰을 얻기 위해서는 Resource Serverclient id, client secret, authorization code, redirect uri 그리고 grant type을 전달해야 합니다. (이 글에서 설명하는 grant type은 authorization_code 입니다)

Resource Server는 받은 파라미터를 저장된 정보와 비교 후 사용자의 Access Token을 반환합니다.

4. API 호출

이제 Client는 사용자의 권한 위임장과 동일한 효력을 가진 Access Token을 얻게 되었습니다.
원하는 API 호출시에 헤더에 Authorization이라는 키를 추가하고 토큰을 담아 전달합니다.

  • Authorization: Bearer

Resource ServerAccess Token의 권한을 검사한 후 Resource를 제공하게 됩니다.


정리하기

클라이언트 입장에서의 순서와 해야 하는 일을 다시 정리해보겠습니다.

  1. 리소스 서버(구글)에 클라이언트(프로그램 P)를 등록한다
  2. Google 아이디로 로그인 이라는 리소스 서버에게 Request를 보내는 링크를 제공한다.
  3. 사용자는 리소스 서버에 로그인을 하고 권한 위임 동의를 거친다.
    • 여기서 클라이언트의 역할은 없다.
  4. 3번이 완료되면 리소스 서버는 1번에 포함된 redirect url로 사용자를 리다이렉트 한다.
    • 클라이언트는 이 요청을 받을 url을 제공해야 하며 authorization code를 파라미터로 받는다.
    • 핸들러의 내부 동작에선 액세스 토큰을 얻는 작업을 구현해야 한다. client id, client secret, code를 리소스서버에 전달하면 액세스 토큰을 얻게 된다.
  5. 클라이언트는 4번에서 얻은 액세스 토큰을 사용하여 리소스 서버 API를 호출할 수 있게 된다.