본문 바로가기

Backend

OAuth 2.0

What is an OAuth 2.0?


https://lh6.googleusercontent.com/PVzOZJQ1tg-FwcSHzpYKJ3MWZG_bzbTNa5kILdfPO68Lo7wN0WsOA5k7Z_MHy_5ltxKgQSQHBl7-qutQE-FRtVEfzTQzl3A8CKDZKUvaHA7EUsjLE9P5tMe7xDBu5Xap8XjtCP7K

 

요즘 대부분의 웹서비스에서 제공해주는 소셜 로그인은 OAuth 2.0 방식을 사용한다. OAuth 라고 하면 뭔가 낯설지만, 소셜 로그인이라면 사용자로서는 매우 친숙한 개념이다. 사용자로서 내가 경험한 '소셜 로그인'은 다른 웹서비스로 하여금 구글/페이스북/인스타그램 등이 가지고 있는 내 정보를 사용할 수 있게 '허가'해주는 과정이었다. 이어질 내용에서는 구체적으로 어떤 과정을 거쳐 이러한 허가가 이루어지는지 알아볼 것이다.

Roles


OAuth 2.0 를 이해하기 위해서는 먼저 누가 참여하는지, 참여자들을 어떻게 부르는지 명확히 해야 한다. Resource Owner 는 Resource Server 에 있는 자원의 오너로, 웹서비스 사용자를 의미한다. Resource Server 는 사용자의 자원이 있는 곳으로 구글, 페이스북 등 소셜 로그인을 제공해주는 서비스들이 이에 포함된다. Client 는 Resource Server 에 Resource Owner 의 자원을 요청하는 주체로, 소셜 로그인을 이용하는 third-party application 이 이에 해당한다. 만약 내가 개발한 웹 서비스에서 소셜 로그인을 사용한다면 내 웹서비스가 OAuth 에서의 클라이언트가 되는 것이다.

How does it work?


Registration

소셜 로그인을 사용하기 위해서는 먼저 Resource Server 에 등록하는 과정이 필요하다.

위는 깃헙에서 새로운 OAuth 애플리케이션을 등록하는 화면이다. Application name, Homepage URL, Authorization callback URL 을 등록해준다. Authorization callback URL 은 사용자가 로그인 및 권한을 승인한 후 리다이렉트 될 URL 이다. 이렇게 애플리케이션을 등록하고 나면 깃헙에서 Client IdClient Secret 을 생성해준다. Client Id, Client Secret, Authorization URL 은 뒤에서 설명하겠지만 리소스 서버에 요청을 보낼 때 클라이언트를 식별하고 인증하는 데 사용된다.

Resource Owner 의 승인

다음으로 클라이언트는 리소스 오너의 승인을 받아야 한다. 클라이언트가 리소스 오너의 승인을 받기 위해서는 일단 사용자를 승인을 할 수 있는 페이지로 리다이렉트 시켜주어야 한다. 깃헙을 예로 들어보자. 사용자가 "Sign in with Github" 버튼을 클릭하면 아래의 URL 로 적당한 인자를 넣어서 리다이렉트 시켜주어야 한다.

GET https://github.com/login/oauth/authorize?client_id=CLIENT_ID

사용자는 권한 승인 페이지로 리다이렉트되고, 클라이언트에 대해서 권한 승인 여부를 결정할 수 있다. 사용자가 권한을 승인하면 리소스 서버는 유저를 클라이언트가 등록한 Authorizaiton callback URL 로 다시 리다이렉트 시켜준다. 이 때 리소스 서버는 Authorization code 를 클라이언트에게 제공해준다. 깃헙의 경우 콜백 url 의 인자(쿼리 스트링)으로 코드를 넣어준다. (다른 소셜 로그인의 경우는 잘 모르겠지만 비슷하지 않을까?)

위의 과정을 간단하게 도식화해보면 위와 같다. 2. 리다이렉트에서 넘겨주는 클라이언트 아이디를 통해 리소스 서버가 클라이언트를 식별 및 인증한다는 점을 기억하자.

Resource Server 의 승인

리소스 오너의 승인을 받았으니 이제는 리소스 서버의 승인을 받아야 한다. 이 단계에서 클라이언트는 Authorization code 를 이용해 리소스 서버의 인증을 받고, 그 결과로 Access Token 을 받는다. Authorization code 와 Access Token 을 교환하는 과정이라고 생각하면 될 것 같다. 이 토큰을 가지고 클라이언트가 리소스 서버에 자원을 요청하게 되므로 매우 중요한 역할을 가진다.

다시 깃헙을 예로 들자면, 아래의 주소로 POST 요청을 보내면 리소스 서버는 Access Token 과 함께 응답해준다.

POST https://github.com/login/oauth/access_token?client_id=?CLIENT_ID&client_secret=CLIENT_SECRET&code=CODE
// Resource Server Response
Accept: application/json
{
  "access_token":"gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "scope":"repo,gist",
  "token_type":"bearer"
}

위의 과정을 도식화해보면 다음과 같다. 리소스서버에서 Access Token 을 얻기 위해서는 Authorization code 외에 client id, client secret 이 있어야 한다. client id 와 달리 client secret 은 외부에 노출되지 않도록 잘 관리해야 한다.

API 호출

이제 클라이언트는 Access Token 을 사용하여 리소스 서버의 API 를 이용할 수 있다. Access Token 이 리소스 오너의 아이디와 비밀번호를 대신하다고 생각하면 된다. 보통 GET 요청 시 Authorization 헤더에 토큰을 넣어주는 방식으로 API 를 호출한다.

Authorization: token OAUTH-TOKEN
GET https://api.github.com/user

 


References

'Backend' 카테고리의 다른 글

SSH  (0) 2021.09.30