본문 바로가기

카테고리 없음

OAuth2

생활코딩의 "WEB2 - OAuth 2.0" 강의를 정리한 내용입니다.

OAuth와 관련해서 3개의 참여자가 등장한다. 각각이 누구인지 살펴보자

  1. mine - 나의 서비스가 있다.
  2. user - 이 서비스를 사용하는 사용자
  3. Their - 나의 서비스가 연동하려는 그들의 서비스가 있다. 구글, 페이스북, 트위터

사용자가 우리 서비스에 접속해서 글을 썼다. 또는 글을 봤다라고 하면 나의 서비스가 사용자를 대신해서 ""구글과 같은 서비스의 칼렌더에다가 날짜를 기록한다""든지 또는 ""페이스북에 글을 썼다라는 것을 공유해준다."든지 이러한 것들을 하고 싶다.

그러기 위해서는 우리가 사용자로부터 그 사용자가 사용하고 있는 그들(Google, Facebook)의 서비스에 접근할 수 있도록 허가를 받아야 된다.

 

가장 쉬운 방법

  • 그들의 서비스에게는 사용자의 아이디와 비밀번호가 있을 것이다.
  • 그것을 사용자로부터 전달받아서 우리가 사용자의 아이디와 비밀번호를 기억하고 있다가
  • 실제로 그들의 서비스에 접속할 때, 사용자의 아이디와 비밀번호를 이용하는 것이다.

아주 간단하고, 그들의 서비스의 모든 기능을 다 사용할 수 있기 때문에 아주 강력한 방법이지만, 위험한 방법이다.

사용자 입장에서 무엇을 믿고 처음보는 서비스에게 맡길 수 있을까. 아주 위험하므로 정보를 넘겨줘서는 안 된다.

 

우리의 입장에서도 사용자의 생명줄과 같은 비밀번호를 우리가 갖고 있기 때문에 이것이 유출됐을 때의 문제는 골치아프다.

그들의 서비스에서도 자신들의 사용자의 아이디와 비밀번호를 신뢰할 수 없는 제 3자가 가지고 있다는 것은 매우 불만족 스러운 상황일 것이다.

이러한 상황에서 우리를 구원해줄 도구가 OAuth이다.

훨씬 더 안전하게 우리가 만든 서비스를 그들의 서비스와 상호작용할 수 있게 해준다.

 

OAuth를 사용할 때 생기는 변화

User의 요청에 의해서 그들의 서비스가 아이디 비빌번호 대신에 accessToken이라고 하는 일종의 비밀번호를 발급한다.

 

이로 얻을 수 있는 장점

첫번째, 그들의 서비스의 id와 password가 아니다.

두번째, 그들의 서비스가 갖고 있는 모든 기능이 아니라 그중에 나의 서비스가 꼭 필요한 필수적인 기능만 부분적으로 허용하는 비밀번호이다.

 

그들의 서비스의 accessToken을 OAuth를 통해서 획득한 다음에 그 accessTokend을 통해서 그들의 서비스에 접근해서 데이터를 가져오고, 수정, 삭제하는 작업을 할 수 있게 되는 것이다.

 

OAuth의 이러한 특징을 이용한다면, 아예 처음부터 회원들의 아이디와 비밀번호를 보관하지 않고, 회원을 식별할 수 있는 기능을 구현할 수 있다.

이렇게 생긴 로그인 기능들을 Federated Identity 라고 하는데, 이것의 가장 기반에 있는 기술이 바로 OAuth 이다.

 

OAuth 라는 복잡한 시스템이 동작하는 핵심 원리를 파해보자


역할

OAuth에 등장하는 3개의 주체에 대한 역할과 용어 정리

OAuth의 핵심 3자 관계

Client

  • mine : 우리가 만든 서비스
  • Resource Server 에 접속해서 정보를 가져가는 클라이언트

Resource Owner

  • User : 우리의 사용자
  • Resource Server 라고 하는 서비스의 회원가입이 되어있어야 한다.
  • Resource Server 의 자원의 소유자 라는 의미

Resource Server

  • Their : Google, FaceBook, ....
  • 우리가 제어하고자 하는 자원을 갖고 있는 서버
  • 데이터를 가지고 있는 서버

Authorizaion Server

  • 인증과 관련된 처리를 전담하는 서버
  • (공식 메뉴얼에서는 두가지를 구분해서 보여준다. 우리는 Resource Server로 통합해서 설명)

 


등록

OAuth를 이용해서 Resource Server에 접속하기 위해서는 우선 Resource Server에 등록하는 과정이 필요합니다.

 

  • OAuth를 등록하는 첫 번째 절차 "등록"

우리의 클라이언트가 Resource Server를 이용하기 위해서는 Resource Server에 승인을 사전에 받아놔야 한다.

 

등록하는 방법을 살펴보자. 서비스마다 등록하는 방법은 다르다.

가장 공통적인 것은 Client ID, Client Secret, Authorized redirect URLs 이 세가지 요소를 공통적으로 받는다.

 

  • Client ID : 우리가 만들고 있는 애플리케이션을 식별하는 식별자 ID → 노출되어도 괜찮다.
  • Client Secret : Client ID의 비밀번호 → 절대로 외부에 노출되어서는 안된다.!!!
  • Authorized redirect URLs : Resource Server가 권한을 부여하는 과정에서 Authorized Code값을 전달해주게 되는데 그때 이 URL을 통해서 전달 받을 수 있다.
    • Resource Server 는 Authorized redirect URLs이 아닌 다른 곳에서 요청이 들어오면 무시하게 된다.

 

실습

1. 페이스북

페이스북 개발자 페이지

1. [My Apps] → [Add New App] → [Create a New App ID] Display Name : 앱 이름 → [Add a Product]

  "Facebook Login" : 페이스북 로그인 기능 구현 → 플랫폼 선택 : "www" 웹을 통한 로그인 기능 구현 할 것이다.

   → Site URL : 우리 사이트의 URL 정보 입력

2. [Facebook Login] > [Settings] > [Redirect URL Validator] Authorized Code값을 요청하여 전달받을 URL 정보 입력

3. [Settings] > [Basic]

    App ID : 우리 앱의 Client ID

    App Secret : 우리 앱의 Client Secret

 

2. 구글

구글 클라우드 플랫폼 - 구글의 경우 클라우드 플랫폼에서 앱을 만들 수 있다.

1. 프로젝트 생성 [Select a project] → [New Project] Project Name : 앱 이름 "Create"

2. 상단에서 프로젝트 선택 → 자신의 프로젝트를 선택

3. 좌측상단에 메뉴 아이콘 클릭 → [Apis & Services]

   우리가 원하는 것은 API를 제어하는 것이다. 제어할 자격(Credentials)을 얻어야 한다.

   → [Credentials] → [Create credentials] > [OAuth client ID]

4. 사용자가 인증하는 과정에서 보여지는 화면 세팅

   [Confugure consent screen] → 

   Product name shown to users : 프로젝트 이름

   Privacy policy URL : (필수 입력이지만 개발 시에는 없어도 됨) "Save"

5. [Create OAuth client ID]

   Application type : Web application

   * Name : 프로젝트 이름

   * Authorized redirect URLs : Authorized Code값을 요청하여 전달받을 URL 정보 입력

 

위 과정이 끝나면 Client ID와 Client secrect 값을 받게 된다.

 


Resouce Owner의 승인

OAuth의 첫번째 절차는 Resource Owner가 Resource Server에게 Client의 접근을 승인한다는 것을 알려줘야 합니다

 

  • 인증을 받는 과정

우리가 "등록"을 진행하게 되면, Resource Server와 Client 는 양쪽다 Client ID, Client Secret, Authorized redirect URLs 정보를 알게 된다.

Client는 Authorized redirect URLs에 해당하는 페이지를 구현하여 준비해 놓고 있어야 한다.

 

Resource Server 가 A, B, C, D 라는 기능을 가지고 있을 때, 이 Client가 리소스 서버의 모든 기능이 필요한 것이 아니라 B와 C에 해당되는 2개의 기능만 필요하다면, 모든 기능에 대해서 인증을 받는 것이 아니라 최소한의 기능에 대해서만 인증을 받는 것이 훨씬 더 서로에게 좋은 방법이다.

 

Resource Owner는 우리(Client)의 애플리케이션에 접속을 할 것이다. 그 접속을 하는 과정에서 우리는 Resource Server를 사용해야하는 상황이 있다. (예를 들어 페이스북에 글을 게시, 구글 캘린더에 날짜를 기록) 작업이 필요하다면 우리는 Resource Owner에게 이러한 화면을 보여주게 될 것이다.

 

페이스북으로 로그인하기, 구글로 로그인하기 등과 같은 페이지를 보여주게 된다.

 

"귀하께서 하시려는 작업은 페이스북의 XX한 기능이 필요한데, 해당 기능을 사용하기 위해서는 인증을 거쳐야 합니다."라는 메시지를 보여준다. 사용자가 동의를 해야 그 다음 단계로 진행할 수 있다.

 

사용자가 "버튼을 클릭"한다는 것은 동의를 한다는 의미로, 해당 버튼에 https://resource.server/?client_id=1&scope=B,C&redirect_url=https://client/callback 이러한 링크를 연결해주면 되는 것이다.

 

→ 해당 버튼의 URL 을 copy해서 URL Decoding 을 하면 보기 편하게 확인할 수 있다.

scope는 구글이 정해놓은 형식에 따라서 scope정보가 들어가 있다.

 

Resource Owner가 위 주소로 Resource Server로 접속하게 되면, Resource Server 가 Resource Owner 가 현재 로그인이 되어있는지 여부를 확인해서 로그인이 안되어 있으면, 로그인을 하라는 화면을 보여준다.

로그인에 성공하면 Resource Servers는 그 때서야 Client_id값과 같은 Client ID 값이 있는지를 확인

자신이 갖고 있는 Client ID의 redirect URL이 접속을 시도하고자 하는 그 요청의 Redirect URL 값과 같은지 다른지를 확인해서 다르면 여기서 작업을 끝내 버린다.

 

그리고 같다면, Resource Owner에게 scope에 해당하는 권한을 Client에게 부여할 것인지를 확인하는 메시지를 전달하게 된다.

"XXX한 것을 XXX한 클라이언트가 요청하고 있다. 허용할 것인가?"

허용 버튼을 누르면 "허용했다."라는 정보가 Resource Server로 전송 된다.

 

그러면 Resource Server는 이러한 정보를 수집하게 된다.

  • user id : 1 (Resource Owner의 user id 가 1번 이라고 가정)
  • scope : b, c

 

Resource Owner의 user id 는 scope b와 c에 대한 작업을 허용하는 것에 동의하였다. 라는 정보를 서버에 저장한다.

 

사용자로부터 리소스 서버에 접속하는 것에 대한 동의를 구하는 과정을 알아보았다.

 


Resource Server의 승인

Resource Server는 Client가 등록된 Client가 맞는지 확인하기 위해서 Resource Owner을 통해서 Client에게 Authorization code를 전달합니다. 이 값을 받은 Client는 이 값과 Client secret의 값을 Resource Server로 전송해서 Client의 신원을 Resource Owner에게 증명합니다.

 

Resource Owner에 대한 허락을 획득 했으므로, 다음으로 Resource Server가 승인을 해줘야한다.

Resource Server가 승인하기 위해서 바로 AccessToken을 발급하지 않고, 하나의 절차가 더 필요하다.

그 때 사용하는 임시 비밀번호가 authorization code이다. Resource Server 는 이 코드를 Resource Owner에게 전송한다.

 

  • Location 헤더 : 응답할 때 Redirection 하도록 한다. 웹브라우저한테 값으로 주어진 URL로 이동하라고 명령하는 것이다.
    " Resource Server 가 Resource Owner의 웹브라우저에게 "
  • ?code=3 : 임시 비밀번호인 authorization code값을 담아서 보낸다.

Resource Owner의 웹브라우저는 Location 헤더 값에 의해서 Resource Owner의 사용자가 인식하지도 못하게 은밀하게 이 주소로 이동하게 된다.

Client는 code 값을 통해서 authorization code값을 알게 된다.

 

Client는 Resource Server에게 authorization code 정보를 전송해서 AccessToken을 발급하기 전 단계까지 왔다.

그러면 Client는 Resource Owner를 통하지 않고 Resource Server에 아래와 같은 주소로 직접 접속한다.

https://resource.server/token?grant_type=authorization_code&code=3&redirect_url=https://client/callback&client_id=1&client_secret=2
  • grant_type=authorization_code : 우리는 현재 authorization_code를 통해서 3자간의 인증을 하고 있다.
  • client_secret 값을 전송하고 있다. (중요 ★)
  • authorization code 값과 client secret 라고 하는 두개의 비밀 정보를 결합해서 Resource Server에게 전송하게 되는 것이다.

 

Resource Server는 전송받은 URL에서 authorization code값에 해당되는 정보와 자신이 갖고 있는 정보가 일치한지 확인한다. 해당 authorization code값이 어떤 Client ID 값에게 발근한 것인지 확인하고 해당 Client ID 값이 가진 Client Secret값을 Client가 전송한 값과 확인한다.

 

그리고 redirect url값을 확인하여 이 정보들이 모두 일치한다면 그 때 AccessToken을 발급해준다.

 


Access Token

OAuth의 핵심인 access token의 값을 발급 받는 과정

 

Resource Server는 이제 authorization code로 인증을 완료하였으므로 이 내용을 지워버린다. 그래야 다시 인증을 하지 않는다.

 

Resource Server는 AccessToken을 발급해서, Client에게 응답해준다.

그러면 Client는 AccessToken 값을 내부적으로 저장하게 된다. (데이터베이스나 파일등에) AccessToken은 을 보장한다.

 

Client가 "accessToken=4"으로 접근하게 되면 Resource Server는 "accessToken=4"를 보고 이 4는 user id = 1 에 해당되는 사용자의 유효한 기능인 b와 c에 대해서 권한이 열려있는 AccessToken이니까 b와 c 그리고 user id = 1에 해당하는 사용자의 정보에 대해서 AccessToken을 가진 사람에게 허용을 해야겠다. 라고 생각하고 동작하게 된다.


API 호출

API가 무엇인지, Access token을 이용해서 API를 호출하는 방법이 무엇인지를 살펴봅니다.

  • API : Resource Server가 Client 들에게 자신들의 자원을 사용하기 위해서 어떻게 하면되는지 정의해놓은 방식

 

(애플리케이션 마다 AccessToken을 가져오는 방법은 상이하므로 AccessToken 값을 발급 받은 후의 과정을 알아본다.)

구글 캘린더 리스트를 보고 싶다면, 해당 api 사용방법과 OAuth 토큰값을 넣어서 API를 요청하는 방식을 알아야한다.

 

 

검색

google calendar api → api doc > [참조]

google api access token oauth → Using OAuth 2.0 for Web Server ApplicationCalling Google APIs

 

 

 

AccessToken을 넣어서 Google API를 호출하는 방법

Calling Google APIs

 

두 가지 방법

  • 쿼리 파라미터로 access_token을 포함시킨다.
  • HTTP Header에 Authorization: Bearer를 넣어서 전송 (이 방법이 선호 된다.)
    이 방식은 표준화된 방식이기 때문에 어디서나 사용할 수 있고 안전한 방법이다.

 

 

토큰값 앞에 bearer 가 무엇일까?
Best HTTP Authorization header type for JWT

클라이언트가 AccessToken(JWT 또는 다른 토큰)을 보내는 가장 적합한 HTTP 헤더는 Bearer 인증 체계가 있는 Authorization헤더 이다.

이 체계는 RFC6750에 정의되어 있다. Bearer는 IANA에 등록되어있다.

 


Refresh token

Access token은 수명이 있습니다. Access token의 수명이 다했을 때 새로운 access token을 발급 받는 방법이 refresh token입니다.

 

검색 : Oauth 2.0 rfc → rfc6749 : OAuth 2.0 인증 프레임워크에 대한 설명이 들어있는 표준 문서
- RFC : 인터넷과 관련된 여러가지 기술들의 표준
Google refresh token

 

 

1.5 Refresh Token

(A) : 권한 획득

(B) : Access Token 을 발급 해준다. 보통 Access Token을 발급받을 때, Refresh Token을 같이 발급 받는 경우가 많다.

(C) : Client는 전달받은 Access Token과 Refresh Token을 저장 해둔다.

api를 호출할 때는 Access Token을 제출해서 Resource Server에 있는 자원을 가져온다.

(D) : 보호되고 있는 자원

(E) : 어느날 AccessToken을 이용해서 자원을 요청하게 된다.

(F) : Invalid Token Error 유효하지 않는 토큰 에러가 발생 ⇒ AccessToken의 유효시간이 만료 된 것.

(G) : Client는 보관하고 있던 Refresh Token을 Authorization Server에게 전달하면서

(H) : Access Token을 재발급 받는다.

문서 내용을 살펴보면, Refresh Token도 계속 갱신되는 곳도 있고, Refresh Token은 갱신되지 않고, Access Token만 갱신되는 곳도 있다.

더보기

(H) The authorization server authenticates the client and validates
the refresh token, and if valid, issues a new access token (and,
optionally, a new refresh token).


공부해볼만한 주제

  • federated Identity : 다른 서비스와의 연합을 통해서 사용자를 식별하는 인증 체계
    Login with Facebook, Login with Google 과 같은 기능들이 바로 이 기술을 이용한 것이다.
  • 주요한 서비스들은 이를 쉽게 구현할 수 있는 방법을 제공하고 있으므로 이를 찾아보자
  • OAuth를 이용하는 궁극의 목적은 API를 제어하는 것이다.
  • 오늘날의 많은 API Restful 한 스타일로 설계되고 있고, API를 통해서 주고 받는 데이터는 JSON, XML 과 같은 데이터 포멧(정보 형태)를 이용하는 경우가 많다.
  • 이런 키워드들에 해당하는 지식을 접해보는 것이 API를 잘 다루는 매우 중요한 배경지식이 될 것이다.