[OAuth 2.0] OAuth의 타입! Grant Type이란?

5 분 소요

안녕하세요. OAuth는 3rd가 사용자의 resource를 다른 서버로 부터 받아오기 위해서 인증을 하는 과정을 뜻하는데요! 그 인증을 하는 과정의 종류로 Grant Type이 나눠지게 됩니다.

Grant Type이란?

정확하게 Grant Type은 허가를 받는 방식(유형)를 뜻합니다. 여기서 말하는 허가는 사용자의 resource에 접근할 수 있는 권한을 뜻합니다. (resource는 외부 서버에 존재할 경우입니다.)

ex) 우리가 app에서 Google로 로그인하기가 가능한 것도 (Google이 아닌데도) OAuth를 통한 인증절차를 거친 App은 우리가 Google에 있는 내 정보를 줘도된다고 허락했기 때문입니다.

그럼 어떻게 허락한지 알 수 있을까요? 바로 accessToken입니다! Client(App)은 accessToken을 HTTP Header에 담아서 보내고, resource를 가지고 있는 server(ex. Google)은 accessToken의 유효성만 체크하고 resource를 내주게 됩니다. 여기서 중요한 accessToken을 발급받는 절차의 종류들을 Grant Type이라고 말하는 것이죠!

일단, OAuth 1.0은 accessToken을 발급해주는 절차가 1가지였지만, 우리가 알아볼 OAuth 2.0 총 5가지 방식이 존재합니다.

Authorization Code

해당 방식은 가장 복잡하면서 가장 많이 쓰이는 방식입니다. 복잡한 건 개발자 기준이지, 사용자 입장에서는 크게 신경쓸게 없습니다. 복잡한 만큼, 나쁜 해커가 가로채갈 위험도로부터 멀어지기도 합니다!

https://github.com/cheese10yun/TIL/raw/master/assets/oauth2-doe-grant-type_gnojt19me.png

위의 그림을 살펴보면 이해가 어려울 수 있습니다. 이를 좀 시나리오적으로 더 풀어서 설명하겠습니다. 일단, Client App(사용자), Client Server, OAuth Server(ex. Google), Resource Server(ex. Google Resource Server)가 존재합니다. OAuth Server와 Resource Server가 하나의 서버로 이루워져 있을 수 있습니다.

  1. Client App에서 구글로 로그인하기를 클릭하면, Client App은 OAuth Server로 인증하기 위한 요청을 보냅니다.
  2. 이때부터, 사용자와 OAuth Server 간의 인증 절차가 진행됩니다. (ex, ID, PASSWORD)
  3. ID, PASSWORD를 OAuth Server로 보낼 때, client_id, redirect_url, response_type를 같이 보내게 됩니다.
  4. OAuth Server는 client_id 즉, 사전에 등록된 client인지를 체크합니다. 그리고 client_id에 mapping된 redirect_url을 체크합니다. (redirect_url이 왜 필요한지는 뒤에서 설명하겠습니다.)
  5. 4번에서 다 성공했을 때, 사용자에 대한 인증을 한 것으로 보고 authorize code를 생성해서 Client에게 반환합니다.
  6. 이때, accessToken이 아닌 authorize code를 반환하는 이유는 accessToken이 Client App에 노출되는 게 싫기 때문입니다. redirect_url?authorize_code=”authorize_code” 형태로 반환합니다.
  7. 저기서 redirect_url은 사전에 등록된 Client Server의 주소입니다.
  8. Client App에서 redirect 된 Client Server로 요청이 가게 됩니다. 이때, authorize_code가 Client Server로 전달되는 것이죠. authorize_code는 일회성이기 때문에 Client App에 노출되도 안전합니다.
  9. Client Server는 authorize_codeclient_id, client_secret를 OAuth Server로 보내서 accessToken을 요청합니다.
  10. OAuth Server는 authroize_codeclient_id, client_secret를 확인해서 accessToken을 반환해줍니다.
  11. Client Server는 앞으로 accessToken을 통해서 Resource Server에 Resource 요청을 하게되고, Resource Server는 accessToken이 유효하다면 Resource를 반환해주게 됩니다.

네, 이런 flow로 진행됩니다. 사실 더 어렵게 느껴지긴 합니다만, 이해하고 나면 크게 어렵지 않습니다. 그리고, 생략된 게 있는데 scope를 통해서 resource에 접근할 수 있는 제한을 두기도 합니다. 이 부분은 여기서 더 설명하지 않겠습니다.

client_secretredirect_url은 사전에 공유된 값이며, 허용된 3rd server에게 정보를 제공하기 위한 조치입니다. client_secret을 대신해서 state(nonce)를 사용해서 CRSF Attack을 막기도 합니다. 이 부분도 여기서 다루지는 않겠습니다.

Implicit

자, 이제부턴 좀 더 간편합니다.

https://github.com/cheese10yun/TIL/raw/master/assets/Implicit%20Grant.png

Authorization Code Grant Type과 달라진 점이 딱 3가지입니다.

  1. authorize_code를 발급하거나 검증을 하지 않습니다.
  2. response_type이 token입니다.
  3. Client Server가 바로 accessToken을 받게 됩니다.

redirect_url에 accessToken을 넣어준다는 것은, URI에 토큰의 정보를 노출한다는 의미입니다. 사용자 입장에서 빠르게 redirect되서 모를 수 있지만, 해커의 경우에는 좋은 먹잇감이 될 수 있습니다.

authorize_code type에서 authorize_code가 노출되는 것은 상관없었습니다. 왜냐하면, 일회성이고 accessToken을 받기 위해서는 client_secret도 알고 있었어야 했으니까요!

근데, 이렇게 accessToken이 노출된다면 해커가 이 정보를 탈취하면 expire_time까지 마음대로 사용자의 resource에 접근이 가능하게 됩니다. 그렇다면 이 방식을 누가 쓸까요? 해당 방식은 ‘브라우저에서 자바스크립트와 같은 스크립트 언어로 동작하는 클라이언트들을 지원하기 위한 승인 유형입니다. 웹 브라우저의 신뢰도가 높고, 신뢰할 수 없는 사용자나 애플리케이션에 노출될 염려가 적을 때 사용합니다.

한 줄 정리를 하자면 Implicit Grant Type은, 복잡한 거 없이 Client가 토큰 발행을 요청하면 최초의 요청만으로 Authorizaton Server가 토큰을 발행한다, 로만 알아주세요.

Client Credentials

네 3번째 토큰 발행 유형입니다.해당 방법은 조금 특이합니다. 대부분 사용자가 시발점이 되는데, 이 방식은 명칭처럼 Client(Service) 그 자체만으로 믿고 토큰 발행을 요청할 수 있는 주체가 되는 방식입니다. 즉, 이 방식은 사용자의 승인(인증) 과정이 생략되어 있습니다.

주로 사용되는 환경도 관리자용 Desktop App이라던가, 혹은 OAuth Provider와 Client간에 신뢰성이 아주 높은 Application에만 사용이 되게 됩니다. 모바일 앱이라면, 해당 앱을 켜는 것만으로도 사용자가 누군지는 상관없고 리소스를 사용할 수 있게 되는 것이니까요.그래서 플로우 차트 또한, 아래와 같이 간략화 될 수 있습니다.

https://github.com/cheese10yun/TIL/raw/master/assets/Client%20Credentials%20Grant%20Type.png

엄청 simple합니다. 설명을 할 필요도 없어보일 정도입니다.

그냥 Client가 토큰 발행을 요청하면, Authorization Server는 토큰을 발행해줍니다.은행에 대출 받을 때만큼 까다로운 심사같은 프로세스가 필요가 없다는 이야기죠.왜냐? 해당 Client는 그만큼 OAuth Provider에게 신뢰가 깊은 존재이거든요(대기업 직원이 은행가면 대출 받기 쉬운 것만큼 신뢰도가 있다는 것이죠)그래서 Client Credentials Grant Type은 너무너무너무 신뢰가 가는 Client이기 때문에 Authorization Server가 묻지도 따지지도 않고 토큰을 발행해주는 방식입니다.

Resource Owner Password Credentials(Password Credentials)

해당 방법을 줄여서 Password Credentials 라고도 합니다. 풀네임은 너무 길기 때문이죠.

해당 Grant Type은 사실 바로 위의 Client Credentials와 아주 흡사합니다.다만, 토큰 발행을 요청할 때 추가되는 정보가 있는데, 그것이 바로 Resource Owner의 Password 입니다. 아, 물론 Resource Owner의 id도 함께 전달됩니다. ID와 Password는 언제나 한 쌍이니까 말이죠.플로우 차트도 Client Credentials와 비슷합니다.

다만, 이젠 다시 Resource Owner의 영역이 추가가 되었죠.

https://blog.kakaocdn.net/dn/ChtsS/btqud6X6Wrg/OSqKMfNFBwBzNOgdh4hYwK/img.png

Resource Owner Password Grant Type Flow

네, 보시면 아시겠지만, 맨 좌측에 Resource Owner영역이 추가되었습니다.그리고 Resource Owner는 Client에게 자신의 id와 password를 전달해줍니다.…말만 들어도 위험해보이죠? 저걸 누가 중간에 채가면 어쩝니까.

채가는 건 그래요 못 채가더라도 Client가 사용자의 id와 password를 알게되는 겁니다. 네이버가 제 아이디랑 비밀번호를 모두 노출한채로 알고 있다고 생각해보세요.

네이버 다니는 친구한테 야, 내 아이디랑 비번 뭐임? 물으면 XX에 OO임. 하고 즉답을 받을 수 있다는 겁니다.거기에 한 가지 더 위험해보이는 영역이 있습니다.토큰 발행을 요청하는 방식이, GET 메소드입니다. 그 말인 즉슨, Authorization Server에 토큰 발행을 요청할 때에 필요한 정보들이 URI에 고스란히 노출된다는 의미인데..정보들의 면면을 뜯어보면 크리티컬한 정보들이 있음을 확인하실 수 있습니다. client_secret, password…이 2개만 봐도 헉? 싶은 정보들이죠.네, 그래서 해당 Grant Type은 Client에 대한 Resource Owner의 100%를 넘어선 1000%쯤의 신뢰도가 바탕이 된다면 사용하시면 되는 방법입니다.Resource Owner와 Client의, 일급기밀(password & secret)을 죄다 끌어모아서 토큰발행을 요청하는 방식, 그게 Resource Owner Password Grant Type 입니다.

Refresh

Refresh Grant Type은 사실 독립적인 방식은 아닙니다. 혼자 독단으로 토큰을 발행하는 방식은 아니라는 이야기입니다. 1~4의 방식대로 accessToken을 발급하고, accessToken은 서버의 resource를 사용할 수 있는 허가를 뜻합니다. 대신, 만료기간이 존재하죠.

만료기간이 존재하는 것은 혹여라도 accessToken이 탈취되었을 때 파기시키는 기능이 기본적으로 존재해야하며, 기본적으로 파기의 주기를 짧게 조절해서 근시간내에 파기되여 무용지물이 되게 하기 위함입니다.

refreshToken은 이를 연장 시키는 개념의 token입니다. refreshToken을 통해서 새로운 accessToken을 발급시크는 방식이죠!

https://blog.kakaocdn.net/dn/rP0if/btquaO59krv/nEjA4pWikdPkI0M5h8NkL1/img.png

Refresh Token이 발행되는 시점이 최초의 Access Token이 발행되는 시점이기 때문입니다.즉, 앞서서 설명했던 Grant Type들로 최초의 인가를 받아야지만 사용할 수 있는 Grant Type이라는 이야기죠.그리고, Authorization Code, Client Credentials Grant Type만이, Refresh Token을 발급받을 수 있다는 사실! 을 꼭 기억해주시기 바랍니다.네, 차별이에요.

Implicit Grant Type과 Resource Owner Pass Grant Type은 Refresh Token이 발급되지 않습니다. Refresh Token이 발급되지 않으니 당연히, Refresh Grant Type도 사용할 수가 없겠죠.정리하자면, Refresh Grant Type은 Authorization Code Grant Type혹은 Client Credentials Grant Type으로 최초에 인가를 받았을 경우, 발급되는 Refresh Token으로 Access Token을 재발행 요청하는 Grant Type이다, 가 되겠습니다.


여러가지의 Grant Type이 존재하지만 Authorize Code를 가장 많이 쓰는 것 같습니다. (공인된 방식인 것 같아요)

마무리

다양한 블로그를 참고해서 작성했습니다. 혹시나 문제가 된다면 삭제하겠습니다.

출처

댓글남기기