티스토리 뷰

자, 이제 본격적으로 OAuth2.0에 대한 이야기를 해보도록 하겠습니다.
여기에 하는 기술 포스팅은 처음이라, 익숙치않은 분들도 계실 수 있습니다만 제 글은 언제나 짧은 몇 줄의 요약 후에 상세한 이야기를 시작합니다. 바로, 아래와 같이 말이죠.

 

오늘 포스팅 주제는 OAuth2.0_이론편입니다. 

(어엉? 이게 요약 끝???  네, 끝^^)

 

짧은 요약이 끝났으니, 이제 긴 본론을 시작해보겠습니다. 레츠꼬.


0. 시작전에..!


우선 많은 분들이 OAuth에 대해서 오해하고 계신 사실부터 짚고 넘어가도록 하겠습니다.
OAuth는 인증을 위해 사용하는 프레임워크가 아닙니다.

 


이 점이 많은 분들이 오해하시는 부분인데
(저도 본격적으로 공부하기 전엔 OAuth는 인증을 위해 쓰는 라이브러리구나, 정도로 알았습니다)

OAuth는 정확히는 인증이 아니라 인가를 위해 사용하는 프레임워크입니다.

 

그래도 제 말을 못 믿으시겠다는 분을 위해서...OAuth2.0의 공식 define 문서를 링크 걸어드립니다.

The OAuth 2.0 Authorization Framework RFC 6749 

위의 문서 링크로 들어가보시면 정확하게 OAuth2.0에 대해서 Authorization Framework라고 적혀있는 것을 확인하실 수 있습니다.

Authorization

네이버든 구글이든 다음이든 파파고든 어디든 무엇이든, 해당 단어를 넣고 돌려보시면 한글로 분명히 ‘인증’이 아닌 ‘인가’라고 번역이 될 겁니다.


그럼 여기서 하나를 더 짚어보겠습니다.


인증과 인가의 차이는 무엇인가?

 

둘은 비슷하면서도 다르고 다르면서도 비슷합니다.

그렇기에 많은 분들이 헷갈려하시고 OAuth2.0을 인증을 위한 프레임워크, 혹은 라이브러리라고 이해하고 계십니다. 실제로 현재 개발을 할 때에도, 흔히 듣던 질문 중에 하나가 '그럼 그쪽 팀은 인증방식으로 OAuth가 적용되어있나요?'였습니다.

(아, 그때 지금만큼 명확히 둘의 차이를 알았다면 당당히 설명 할 수 있었을텐데...무지몽매했던 과거의 나란 놈..ㅠㅠ)

 

본래 어떠한 말의 정의를 명확히 이해하고 습득하기 위해서는 뜻을 보는 게 중요한 법입니다.

우리는 한국인이지만, 이 글도 한글로 포스팅을 하지만 영어부터 살펴보도록 하겠습니다.

인증은 영어로 Authentication입니다.
인가는 영어로 Authorization입니다.

두 단어 모두 Auth를 prefix로 시작하지만, 뒤는 전혀 다릅니다. 뒤가 다른만큼 둘은 서로 다른 의미를 가지고, 활용될 때에도 다르게 쓰입니다 (물론 '인증'과 '인가'에 대해 매칭 된 영단어가 더 있지만, OAuth2.0과 관련된 Java 라이브러리내에서는 저 2개의 단어로 클래스명이 작성되어 있기에 일단 무시합니다)

단어에 매칭된 영어를 봤으니 이젠 우리가 익숙한 한글에서의 정확한 뜻을 알아보도록 하겠습니다.

네이버에서 국어 사전을 뒤적거려봤습니다.

인증 :네트워크나 서버에 접속할 때, 본인 여부와 정규 이용자 여부를 확인하는 방법. 일반적으로 사용자 아이디와 패스워드의 조합으로 본인을 특정한다
인가 :특정한 프로그램, 데이터 또는 시스템 서비스 따위에 접근할 수 있는 권한이 주어지는 것

네, 영어도, 한글도 둘은 서로 다른 의미를 가진다는 것을 확인하실 수 있습니다.

그리고 다시 한 번 주지하지만 OAuth는 인가를 위한 프레임워크입니다.

또한, 이때 인증과 인가의 관계에서 가장 중요한 포인트가 등장하는데, 이는 인가는 인증이 선행되지 않으면, 애초에 시도해 볼 수조차 없다, 라는 것입니다.
(실제로 spring-security-oauth2 라이브러리를 이용하여 OAuth를 구현한 후, 디버깅을 통해서 라이브러리내의 .class파일들을 따라가다보면 Authentication 객체를 통해 사용자의 인증이 선행되었는지를 체크하고, 인증이 되어있지 않다면 인가도 하지 못 하도록 되어있습니다.)


1) OAuth에 필요한 4요소

캡틴플래닛을 소환하기엔 하나가 모자라지만, 그냥 그러려니 합시다.

짚을 점을 짚고 넘어왔으니, 다시 본론인 OAuth에 대해 이야기를 해볼까 합니다.

1. Resource Owner : 사용자, 고객, 너, 혹은 나, 우리.
2. Client : 리소스(데이터)에 접근하고자 하는 서비스.
3. Authorization Server : 인가의 주체. 주최ㄴㄴ 주체ㅇㅇ. 토큰을 발행해주는 것이 주역할.
4. Resource Server : 인가서버가 발급한 토큰을 확인하고 리소스를 제공하는 역할.
(Authorization Server와 Resource Server를 묶어서 OAuth Provider라고도 합니다)

뜬금없이 4가지 요소를 각각 한 줄로 정리해봤습니다.
다시 한 번 찬찬히 읽어봐주세요.

위에 4가지는 OAuth를 개발할 때 필수적으로 사용되는 개념이자 존재해야 하는 것들입니다. 

그렇기에 필수라고 말을 했듯이 없으면, OAuth가 성립되지 않는 것들입니다.


1) Resource Owner

Resource Owner에 대해서는 크게 설명을 하지 않아도 한 방에 이해를 하셨을 거라고 생각합니다. 

간략하게 서비스를 이용하는 사람들, 이라고 생각하시면 됩니다
(너와 나의 연결고리 이건 우리 안의...죄송합니다, 월요일이라 드립력이 난무하네요...)
 
해당 개념의 명칭이 Resource Owner인 이유는, OAuth2.0에서 제시하는 ‘리소스’의 개념이 개발적인 측면에서 보자면 서버가 가지고 있는 데이터, 혹은 프로세스들을 뜻하기 때문입니다.

그리고 그 리소스에 대해서 CRUD를 하고자 하는 주체는 이 글을 맨눈으로 보고 계실 여러분이고 그러한 여러분의 행동(클릭이든 인풋이든 엔터든 뭐든)을 통한 요청이었을 것이기 때문입니다.

(CRUD는 Create, Read, Update, Delete로써 데이터에 대해 각각에 알맞은 작업을 하고자하는 것을 의미합니다.)


예를 들어봅시다
여러분이 지금 보고 계시는 이 포스팅이 있습니다.
골결정력 떨어지는 3류 스트라이커마냥 드립력이 난무하는 이 포스팅을 보기위해서 여러분은 티스토리에 접속을 하고 제 블로그에 오셔서 수많은 리스트에서 해당 글을 클릭 하셨을 겁니다.

바로 그 클릭이라는 행동을 했을 때, 여러분은 서버에게 ‘나 이 글 좀 보고 싶은데 본문(Resource) 좀 가져와’라고 소유자(Owner)의 입장에서 요청을 하신겁니다. 그리고 그 요청에 따라 리소스는 읽혀왔고, 브라우저는 리턴된 리소스를 바탕으로 화면을 구성하여 이렇게 여러분이 읽고계신거죠.

이미 여러분은 본 사이트에 로그인을 하셨습니다. 인증을 받으신거죠.

(구글이나 기타 검색을 통해서 오셨을 경우는 가정하지 않았습니다)

그리고 인증을 받으면서 인가를 받으셨을 겁니다.
관리자로 인가를 받지는 않으셨을거에요, 여러분은 티스토리의 어드민이 아니니까요.

인증 및 인가를 통해서 확인을 받고 리소스에 대해 접근을 할 수 있는 소유자, 

그게 Resource Owner입니다.


2) Client

조...금 헷갈릴 수도 있는 명칭입니다. 
특히나 저와 같이 웹개발을 하시는 분들이라면 더 헷갈리실 수 있습니다. 
왜냐면 제게 클라이언트는 서버 말고 그거,할 때의 클라이언트가 Client였기 때문입니다.

당신이 웹개발을 하는 사람이라고 가정을 합시다. 
그렇다면 당신은 보통 Spring Framework으로 서버(백엔드)를 구축 할 겁니다
(코틀린으로 하거나 파이어베이스를 이용한 Serverless로 구축하실 수도 있지만, 그 정도까진 일단 넘어갑시다...)

그리고 요근래에는 React.js, Vue.js, Angular.js와 같은 Front-end Framework를 사용해서 클라이언트를 개발합니다. 

네, 그렇습니다. 
우리가 흔히 웹브라우저로 띄워서 보는 ‘화면’과 화면을 이루는 코드상에서 이루어지는 로직(서버까지 요청하지는 않는)이 구현되어있는 부분을 저는 클라이언트라고 머릿속에 넣어뒀습니다.

그래서 누군가 제게 Client라는 개념을 묻는다면, 가장 먼저 떠오르는 개념이 이미 정해져 있던 상태였습니다. 
하지만 OAuth에 정의되어 있는 Client는 거기까지로 끝나는 게 아니었습니다. OAuth의 Client는 ‘서버와 클라이언트’로 이루어진 하나의 서비스 그 자체를 Client라고 묶어서 부르고 있었습니다.

아마 인터넷 쇼핑을 자주하시는 분들이라면 그런 화면을 자주 보셨을 겁니다.
특정 사이트에서 로그인을 하려고 할 때, 페이스북으로 로그인 이라던가 카카오아이디로 로그인, 네이버로 로그인과 같은 버튼들을요.

쉬운 이해를 위해 또 예시를 들겠습니다.
여러분은 지금 G마켓의 서비스를 이용하려 합니다.

G마켓에 접속하여 브라우저에는 녹색의 심볼마크가 뙇,하고 박힌 G마켓의 홈페이지가 띄워진 상태일 겁니다.

그리고 여러분은 G마켓의 서비스를 이용하기위해 로그인을 하려고 하는데, 때마침 그곳에 네이버로 로그인 버튼이 있습니다. 

대한민국 사람중에 네이버 아이디가 없는 사람은 흔치않습니다. 당신도 아마 있을 겁니다.

그러니 굳이 G마켓에 회원가입하는 건 귀찮아, 난 네이버 아이디로 로그인 할 거야! 라고 당신은 마음먹었습니다. 

난 그냥 G마켓 회원가입 할꾼데? 난 G마켓 아이디 있눈뒈에?? ...이러지는 맙시다.

...그래서 네이버 아이디로 로그인 버튼을 누르면, 네이버에서 제공하는 로그인 화면이 나올 겁니다. 

그리고 당신은 네이버 아이디와 비밀번호로 G마켓에 로그인을 하게 되었고 해당 인증을 바탕으로 G마켓에 있는 검색, 장바구니 담기, 구매, 반품, Q&A등의 서비스를 이용할 수 있게 된 것입니다.

이쯤에서 Client에 대한 생각을 다시 떠올려보도록 하겠습니다.
여러분이 이용하려는 서비스는 G마켓이었습니다, 분명히.
하지만 여러분이 아이디와 패스워드를 이용해서 인증을 받은 곳은 네이버였습니다.
네이버에서 받은 인증을 바탕으로 G마켓의 각종 서비스를 이용하실 수 있게 된겁니다.

위에서 설명했던 Resource Owner는 G마켓에 로그인을 하려했던 당신입니다.

그렇다면 G마켓은요? 
당신이라는 Resource Owner가 실질적으로 사용하려고 했던 서비스입니다.

그와 동시에 OAuth Provider(여기서는 네이버가 됩니다)에게 Resource Owner의 로그인을 요청하는 요청자가 되죠. 그리고 로그인한 이후에도, Resource Owner가 Client(G마켓)의 서비스를 이용하면서 OAuth Provider의 리소스(데이터)를 필요로 한다면 추가로 요청을 하는 역할을 하게 됩니다.

본인만의 서비스가 있으면서 Resource Owner의 요청에 따른 OAuth Provider의 리소스에 접근을 요청하는 역할,그게 Client입니다.


3) Authorization Server

Client가 가장 큰 산이었습니다. 그 덕에 설명도 부단히 길어지게 되었습니다.
남은 2개의 개념은 심플합니다. 사실 크게 설명할 것이 없습니다.

Authorization Server는 인가의 주체자, 라고 제가 한 줄로 정의를 했습니다.
여기서 의미하는 ‘주체’는 말그대로 OAuth에서 주가 되는 역할을 하기 때문입니다. 

제가 앞에서 먼저 언급하는 것을 깜빡했는데 OAuth는 토큰을 기반으로 하는 인가 프레임워크입니다.
(여기서 토큰에 별 4개 땅땅땅)

인증을 받은 이후에, OAuth로 인가를 받으면 Access Token이 발급됩니다. 
이후 요청하는 모든 건에 대해서는 리소스 서버가 해당 토큰을 바탕으로 인가받은 클라이언트인지를 확인하고 사용 가능한 토큰인 경우 리소스에 대한 요청을 처리하는 것이 기본 프로세스입니다.

그리고 이때에 필수적으로 쓰이는 토큰(정확히는 Access Token이라고 합니다)을 발행하는 곳이 Authorization Server입니다.

Access Token을 발행하는 과정은 생각보다 복잡하고 이를 위해 설정하는 사항도 많습니다
(심플하게 하려면 할 수는 있는데, 아시겠지만...세상사라는게, 코딩이라는게, 개발한다는게, 인터넷 예제들은 척척 촥촥 심플심플하게 되서 밥아저씨처럼 참 쉽죠? 라고 포스팅 되어 있는데 왜 내가 하려면 안 되고 그대로 가져왔는데 콘솔엔 에러만 찍찍이고 이 코드는 왜 쓴 건지 삼척갑자 동방삭 외우는 것처럼 1도 모르겠고 알 수 없는 요지경...)

그래서 여기서는 개념적인 부분만 짚고, 조금있다가 상세하게 설명을 하려합니다.
다시 한 번 언급 겸 정리하자면 Authorization Server는 Resource Owner가 Client를 통해서 리소스에 접근하려고 할 때, 필요한 Access Token을 발행해주는 곳이다, 라고 알아주세요.

4) Resource Server

드디어, 마지막 개념, Resource Server입니다.

...Resource Server라고 하니 서버인 거 같습니다.
처음엔 Resource Server 라고 되어있길래 DB까지 포함해서 리소스를 가지고 있는 서버단 모두를 뜻한다고 이해했습니다

(많은 블로그와 설명들이 그렇게 말하고 있기도 합니다)

하지만, 실제로 www.oauth.com 에 있는 문장을 해석해보면 리소스 서버는 Access Token을 얻은 Application의 인증받은 요청에 대해서 핸들링 한다고 되어있습니다.
(원문 : The resource server is the OAuth 2.0 term for API server. 

The resource server handles authenticated requests after the application has obtained an access token.)

여기서, 유심히 봐야할 부분은 저기서 말한 ‘핸들링’을 어디까지로 볼 것인가, 입니다.
해당 페이지에서 스크롤을 조금만 더 아래로 내려보면 Resource Server가 하는 역할을 크게 3가지로 명시해놓았습니다.

Verifying Access Token : Access Token의 확인
Verifying Scope : Scope의 확인(Scope는 각 Client가 가지는 리소스에 대한 권한의 개념)
Error Codes and Unauthorizaed Access : 에러코드및 비인가 접근에 대한 처리.

어디에도, 리소스를 가진 서버라는 말이 없었습니다.

오히려 제가 이해하기에는 Authorization Server로 부터 발급받은 토큰을 확인하거나, 인가받았는지 여부를 확인하는 문지기 역할인 것 같았습니다.
(실제로 개발시에 @EnableResourceServer 어노테이션을 통해서 Resource Server를 사용하겠다는 정의를 해 둘 경우, Spring Security가 제공하는 필터 프로세스 도중에 OAuth2AuthenticationProcessFilter라는 필터가 하나 더 추가되어 동작되는 것을 확인할 수 있었습니다)

이 설명을 했을 때 한 선배가 말하길,

그럼 Authorization Server는 매표소고, Resource Server는 검표하는 곳이네.라고 하시더군요.

저는 이 표현이 Authorization Server와 Resource Server를 정의하는 정확한 말이라는 생각이 들었습니다.

즉, Resource Server는 서버라고 명시되어있고 그렇게 불리지만, 실제로 하는 역할로 본다면 필터에 가까운 모습이고, 개발하는 입장에서 코드적인 관점으로 보자면 토큰기반의 인가 체계를 구축하고 있는 OAuth2에서, Authorization Server가 발행한 토큰이 유효한지를 확인하기 위해서 사용하는 필터가 있는데, 그 필터에 대한 세부 설정값을 정의해주는 요소, 라고 보시면 되겠습니다.

5) 4요소에 대한 정리

설명이 길어지고 있으니 짤막하게 정리해보겠습니다.

G마켓(Client)이라는 서비스를 통해서 물건을 검색해보고 구매하려는 사용자(Resource Owner)는, G마켓에 접속을 하려합니다.


G마켓은 사용자가 네이버 아이디로 로그인을 원할 경우를 대비해서 네이버(OAuth Provider : Authorization Server & Resource Server)를 통해 인증/인가를 하는 기능을 넣어두었습니다.


이때 사용자는 번거롭게 G마켓에 가입할 필요없이 네이버 아이디로 로그인을 하고, 네이버는 G마켓에게 Access Token을 발급하며, 이후 G마켓은 네이버로부터 필요한 리소스(닉네임, 주소, 전화번호)가 있을 경우, 발급받은 토큰을 바탕으로 요청을 하게 됩니다.


글이 또 길어지고 말았네요.
평소 제 글버릇이 사족에 오족까지 붙여대는 타입이다보니 좀 많이 길어지게 되었습니다. 
그래도 이렇게 세세하게 하나하나 풀어 쓰지 않으면 10년 뒤의 제가 봤을 때 이해할 수 없기 때문이니 이해해주시길 바랍니다.
(드립만 줄였어도 분량이....)

사실 한 편으로 끝내려 마음먹고 쓰기 시작한건데, 글렀네요.
OAuth에 대한 포스팅은, 다음편에 계속하도록 하겠습니다.

댓글
최근에 올라온 글
Total
Today
Yesterday