본문 바로가기

MAC(Intel, M1) WINDOW

Oauth2.0에 대하여

728x90

 

SNS로그인에 필요한 지식

 

꼭 sns로그인에만 쓰이는 것은 아님

구글 캘린더에 일정을 기록하거나, 페북 게시글 공유 등 

 

federated identity : 다른 서비스와의 연합을 통해 사용자를 식별하는 인증체계

대체 클라이언트/리소스오너/리소스서버가 어떻게 서로를 신뢰하여 소통할 수 있을까?에서 출발한 기술 

궁극의 목적은 API제어하는 것, (요즘의 API는 Restful style로 설계되며 JSON형식으로 데이터를 받고보낸다)

 

 

이 3가지의 연동이 일어남 

  • 내가 개발한 나의 서비스  
  • 사용자
  • 내가 연동하려고 하는 다른 서비스(구글, 네이버, 카카오,페이스 북, 트위터 등)

 

가장 쉬운 방법은

나의 서비스가 사용자에게 다른 서비스의 ID/PW를 물어본 후 

 그 ID/PW를 그들의 서비스를 이용할때 넘겨주고 서비스를 요청한다! 

but, 사용자는 처음보는 나의 서비스를 fully 신뢰하여 id/pw를 넘겨주기 조금 그렇다

+ 나의 서비스에서는 그것을 받아서 관리해야하므로 매우 부담이 크다! 

 

=> 이 모든 상황을 해결해 주는 것이 oAuth ! 

우리의 서비스와 그들의서비스 가 상호작용 가능하다! 

 

oAuth는 accessToken을 사용하는 방법!!

장점은

1. 실제 아주 민감한 정보인 ID/PW를 사용하는 방식이 아니다

2. accessToken은 해당 서비스의 모든 기능이 아닌 허용한 특정 기능에 대한 엑세스만을 가능하게 한다! 

 

 

OAuth를 이용해 AccessToken을 얻어내는 원리

 

용어정리 

3개의 주체부터! 

우리가 만든 나의 서비스 : Client 

그들의 서비스(페북, 구글,네이버 등등) : Resource Server 

사용자 : Resource Owner

+ Authroization server 라는 것이 하나 더 나오는데 

Resource Server란 Client가 접근하고 싶은 정보(data) 를 가지고 있는 서버

Authroization Server :인증과 관련된 처리를 담당하는 서버 -> 따로 언급하지 않고 Resource Server에 묶어서 생각하기도 한다

 

 

 

과정 1.  Register : 등록 

Client가 Resource Server가 가진 Resource Owner의 정보에 접근하기 위하여 사전에 승인을 받아두는 것을 말한다.

 

Resource Server마다 register방식은 다르지만 공통적인 것은

Client ID : Client(우리가 만든 서버)를 식별하는 고유 값 -> 노출 가능

Client Secret : Client가 가진 비밀번호 -> 노출 불가! 

Authoized redirect URIs : Resource server가 권하는 부여하는 과정에서 auth code를 부여하는데, 이를 받을 주소 (이 주소에서 온 요청만 받을 수 있음)

를 가진다는 것

등록 과정을 진행하면, 이제 Resource Server와 Client는 Client(나의 서버)의 

Client id/secret , redirect URL(이건 당연하게도 개발한 나의 서버에서 구현을 해둬야한다)을 보유하고 있다! 

참고로 구글 등록과정은 이렇다

여기서 참고사항 Client는 자신이 필요로 하는 Resource Server의 기능에 대해서만 등록을 하는 것이 좋다! 

-> 예를 들어 구글에서는 구글 캘린더/구글 로그인 등등의 기능을 보유하고 있지만,

구글 로그인기능만 필요한 것이라면 구글 로그인 기능에 대해서만 등록/승인을 받는 것이 좋다 

 

 

 

 

 

2. Resource Owner의 승인 

Resource Owner가 Client에 접속하여 하려는 작업중에 Resource Server의 기능을 필요로 한다면,

Client는 Resource Owner에게 다음과 같은 화면을 보여준다 

- ㅇㅇ(Resource Server)로 로그인 하기

또한, 만약에 최초라면 

- 해당 기능은 ㅇㅇ의 기능을 필요로 하며, 인증이 필요합니다

등의 화면을 보여준다 -> 사용자의 동의를 받음! 

사실상 이러한 버튼들을 클릭하면 사용자는 동의한다는 의미로 동의를 받은 것인데,

https://resource_server/?client_id={클라이언트아이디}&scope={사용하려고 하는 기능 범위}&redirect_uri={uri} 

를 버튼에 연결해주기만 하면된다.

 

Resource Owner가 Client를 통해 위의 link로 접속하게되면, Resource Server로 요청을 보내는 것인데, 

만약 Resouce Owner가 현재 Resource Server에 로그인이 되어있지 않다면, 로그인을 먼저 요청하고

로그인에 성공한 경우 Resource Server는 위의 link 의 파라미터로 넘어온 client_id를 이용해 자신에게 register된 client가 맞는지 확인하고, 그 후 register된 client라면 redirect url이 자신이 가진 것과 파라미터로 넘어온 것이 맞는지 확인한다.

(맞지 않으면 종료) 

맞다면, Resource Server는 다시 Resource Owner에게 이와 같은 scope(기능/데이터)에 Client가 접근하는 것을 허용하는지 질문을 한 후 

Resource Owner가 허용버튼을 누르게 되면 Resource Server로 허용 respond가 돌아간다.

그렇게 되면 이제, Resource Server는 저장해 두었던 Client_id / Client Secret / redirect URL 과 더불에 

Resource Owner의 id(구분할 수있는 key값)과 해당 Owner가 허용한 scope 두가지를 추가로 저장해 둔다.

 

이렇게 되면, Resource Server는 이제 다음과 같은 정보를 보유한 것 

Resource Owner "A"는 Client "a"에 B/C(scope)기능을 허용했다! 

 

 

 

 

3. Resource Server의 승인 

Resource Owner가 자신의 정보를 내어줄 것을 승인하였으니, 이제 Resource Server에서 자신이 가진 정보를 Client에 내어주겠다는 것을 승인 받아야한다.

이떄 사용하는 것이 "authorization code" 바로 임시 비밀번호다 ! (승인했다고 바로 accessToken을 주고받는 것은 위험!) 

Resource Server는 자신이 가진 client의 redirect url에 파라미터로 auth code를 담아 resource owner에게 전송한다.

Location : https://client_redirect_url?code={code}

*Location은? 응답시에 header에 location이라는 값을 주면(redirection), 다음과 같은 주소로 이동하라고 resource server가 resource owner의 web browser에 명령한 것 

-> 따라서 Resource Onwer는 자신이 의식하지도 못한 사이에 다음과 같은 주소로 이동하게된다 

그리고 다음과 같은 주소! 라는 것은 client가 직접 응답을 받을 주소를 적어둔 것이므로, client에게로 "authorization code"를 가지고 돌아가는 것이 된다 

이제 Client는 authorization code(임시 비밀번호)를 보유하게 되었다! 

 

 

4. accessToken의 발급

Client id / Client secret / auth code까지 보유하게된 Client는 이제 자신이 가진 정보를 이용해서 

Resource Owner를 거치지 않고, 직접 Resource Server에 Request를 보내게 된다

다음과 같은 파라미터를 포함한다

  • grant type : 인증방식을 어떤 방식을 이용할 것인가? (여기서는 auth code 방식을 이용) -> 4가지 정도의 방식이 있다.
  • code : 가지고있는 auth code( 임시 비밀번호 )
  • redirect url : 응답을 받을 url 
  • client id : Resource server에서 client를 식별할 id
  • client secret 

https://resource_server/token?grant_type=authorization_code&code={auth_code}&redirect_uri={url}&client_id-={id}&client_secret={cli_secret}

다음과 같은 링크로 request를 받게되면, 

code를 확인하여 자신이 가지고 있는  code와 비교한다. 해당 code를 기반으로 그 코드와 연결된 client_id/secret/url이 전부 일치하는지 확인한다 

확인이 완료되었으면, code를 지우고 accessToken을 발급한다 

 위의 request에 대한 응답으로 accessToken을 넘겨준다

그러면 이제 Client는 response로 받은 accessToken을 저장해둔다! 

이제 accessToken을 이용하여, Resource server에 요청이 가능하다! 

 

 

5. API 호출 : accessToken을 이용하여 원하는 서비스를 이용하기

*API(Application Programming Interface) 는 client 와 server간에 어떤 서비스나 데이터를 요청reqeust 하고 응답(response)받아 사용하는 절차/방식을 약속해둔 것

API를 사용하는 방식은 (API는 약속이기 때문에 원하는 특정기능에 대한 api가 문서상에 정리되어 있다)

ex) 구글 캘린더 api

https://www.googleapis.com/calendar/v3/users/me/clandarList/ {calendarID}( -> 이게바로 약속한 형식API!) 로 접속하면 유저의 캘린터리스트를 제거 하는 기능을 사용가능하다!

 

API를 요청하는 방식은 

https://developers.google.com/identity/protocols/oauth2

 

OAuth 2.0을 사용하여 Google API에 액세스하기  |  Google ID 플랫폼  |  Google Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. Switch to English OAuth 2.0을 사용하여 Google API에 액세스하기 참고: Google의 OAuth 2.0 구현에는 OAuth 2.0 정책이 적용됩니다. Google API는 인증 및 승인

developers.google.com

각 Resource Server의 document를 참고하여, api+accesstoken을 사용하면된다! 

여기 두가지 방법을 중심으로 살펴보면

파라미터로 accessToken을 넣어 인증이 된 client+resource owner 임을 증명하는 방법

Header 에 Authorization : Bearer "accessToken"을 넣어 증명하는 방법

두가지를 소개하고 있으며, 당연히 후자가 안전하다.

 

 

 

 

참고 : Refresh Token

accessToken들에는 수명이 있다! (몇시간~60일 정도) 

이렇게 수명이 끝나면 인증을 받을수가 없게되므로 다시 발급받아야하는데 이때 refreshToken을 사용하면 쉽게 받을수 있다.

 

설명을 볼수 있는 곳 

https://www.rfc-editor.org/rfc/rfc6749.txt

 

보통 access token 발급시에 refresh token(유효기간이 아주 김)을 함께 발급하여준다.

client에서 api를 호출할 때는 accesstoken을 사용하여 resource server에 본인을 인증하고 데이터를 가져오는 등 resource server의 서비스를 사용한다.

그런데 만약 AccessToken이 만료되면, invalid token error를 받게되는데, 

그렇게 되면 보관하고 있던 refresh token을 전달하여 access token을 다시 발급받는다 

 

 

 

 

 

https://youtu.be/XpBf7ZiT_do

 

 

 

728x90