이 글은 생활코딩 강의를 토대로 개인적으로 이해한 내용을 덧붙여 작성하였습니다.
사용자 sang5c
가 구글에 가입되어있고, OAuth 인증을 통해 사용자의 정보를 프로그램 P
가 Google
에게서 얻어오는 과정을 예로 들어 설명합니다.
OAuth는 sang5c
가 P
에게 비밀번호를 제공하지 않고도 Google
에 저장된 자신의 정보에 접근할 수 있는 권한을 부여할 수 있는 수단입니다. OAuth 인증이 완료되면 P
에게 사용자의 토큰이 발급되며, 이 토큰을 사용하면 Google
에 사용자를 대신하여 요청을 보낼 수 있습니다.
간단히 OAuth를 정리해보자면, OAuth는 사용자의 토큰을 얻기 위한 과정이다. 토큰이 있으면 사용자의 권한이 있다(API를 호출할 수 있다). 라고 할 수 있습니다.
용어 / 역할 정리
얻고싶은 자원인 사용자 sang5c
의 정보를 Resource
라 칭합니다. 사용자는 이 리소스의 주인이기 때문에 Resource Owner
입니다.
구글은 사용자의 정보를 저장하고 있으며, 사용자의 동의를 얻어 이 정보를 제공할 수 있습니다. 따라서 Resource Server
라 호칭합니다. 이 글에선 설명의 편의를 위해 Authorization Server
를 언급하지 않았으며, Resource Server
와 동일하다고 가정하고 설명합니다.
프로그램 P
는 Resource Server
에게 사용자의 정보를 요청하는 입장입니다. 따라서 Client
라 호칭합니다.
사용자 -> Resource Owner
프로그램 P -> Client
Google -> Resource Server
1. 등록
Resource Server
는 아무에게나 Resource
를 제공해선 안됩니다. 미리 등록된 Client
만 리소스를 사용 가능하도록 제한합니다.
리소스 서버를 사용하기 위해 사전에 승인 받는 과정을 등록(register)
이라 부릅니다.
등록 과정에선 RedirectURI
를 등록해야 합니다. 이 URI는 Client
가 API를 정의한 URI이며, Resource Server
에게서 Resource Owner
의 Access Token
을 얻는 작업이 이루어집니다. 이 작업은 잠시 뒤 설명합니다.
등록이 완료되면 Client
는 Client ID
, Client Secret
를 얻게 되며, 이는 Redirect URI
와 함께 Resource Server
에 저장됩니다.
2. OAuth 로그인
Client
는 Resource Owner
에게 Google ID로 로그인 버튼을 만들어서 제공해야 합니다.
이 버튼은 Resource Server
에게 요청을 보내는 기능을 하며, 파라미터로 미리 발급받은 client id
와 원하는 권한의 scope
, redirect uri
를 같이 전달 하도록 구성합니다.
사용자가 이 버튼을 누르면 구글로 연결되며, 로그인이 되어있지 않다면 로그인을 진행한 후 권한 위임에 대한 확인을 받습니다.
주목해야 하는 점은, 이 과정을 Client
는 관여하지 않습니다. Resource Owner
와 Resource Server
가 과정을 진행합니다.
로그인이 이루어지고, 권한 위임에 대한 동의가 완료되면 Resource Server
는 같이 전달한 Client ID
와 Redirect 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 Server
에 client 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 Server
는 Access Token
의 권한을 검사한 후 Resource
를 제공하게 됩니다.
정리하기
클라이언트 입장에서의 순서와 해야 하는 일을 다시 정리해보겠습니다.
- 리소스 서버(구글)에 클라이언트(프로그램
P
)를 등록한다 Google 아이디로 로그인
이라는 리소스 서버에게 Request를 보내는 링크를 제공한다.- 사용자는 리소스 서버에 로그인을 하고 권한 위임 동의를 거친다.
- 여기서 클라이언트의 역할은 없다.
- 3번이 완료되면 리소스 서버는 1번에 포함된 redirect url로 사용자를 리다이렉트 한다.
- 클라이언트는 이 요청을 받을 url을 제공해야 하며 authorization code를 파라미터로 받는다.
- 핸들러의 내부 동작에선
액세스 토큰을 얻는 작업
을 구현해야 한다. client id, client secret, code를 리소스서버에 전달하면 액세스 토큰을 얻게 된다.
- 클라이언트는 4번에서 얻은 액세스 토큰을 사용하여 리소스 서버 API를 호출할 수 있게 된다.