Skip to main content

Command Palette

Search for a command to run...

OAuth 2.0

Updated
3 min read
OAuth 2.0

OAuth 2.0 프로토콜은 외부 서비스의 권한 위임에 위해 사용되는 프로토콜입니다.

OAuth 2.0 RFC 공식 문서

OAuth2.0은 왜 필요했을까?

일반 사용자들이 앱을 통해서 Google이나 제 3자 서비스들에 저장된 자기 정보에 접근하기 위해서 가장 간단한 방법은 제 3자 서비스의 비밀번호를 앱에 공유하는 것입니다.

하지만, 이러면 "앱"은 사용자들의 제 3자 서비스 계정의 비밀번호를 알게 되고 관리해야하며, 이는 보안상 중요한 정보입니다.

이를 해결하기 위해서 OAuth2.0이 등장했습니다.

OAuth 1.0과의 차이점

동일한 문제를 해결하기 위한 프로토콜로서 OAuth 1.0이 있었습니다.

공식문서에 의하면 OAuth2.0은 기존의 비밀번호 공유 모델의 한계를 해결하고, 안전하고 세분화된 위임(access delegation)을 표준화하기 위해 만들어졌습니다.

OAuth 1.0

OAuth 1.0은 “서명 기반(Signature)” 위임 프로토콜입니다.

역할: Consumer(클라이언트), Service Provider(자원/권한 서버 역할 겸함), Resource Owner(사용자).

토큰 체계: request token(임시) → access token(영구) 각각에 secret(비밀키) 가 쌍으로 있음. 매 요청을 토큰/컨슈머 시크릿으로 서명해서 보냄.

서명·보호: HMAC-SHA1, RSA-SHA1, PLAINTEXT 등 서명 방식 + nonce/timestamp로 재사용(재전송) 공격 방지. 요청 요소들을 합친 Signature Base String을 만들어 서명.

  1. Request Token 획득 클라이언트가 서명한 요청으로 request_token 받음(콜백 URL 포함). 1.0a에선 응답에 oauth_callback_confirmed=true. 

  2. 사용자 승인 & Verifier 발급 사용자를 서비스 제공자의 승인 페이지로 리디렉트 → 승인 후 클라이언트 콜백으로 oauth_token + oauth_verifier 전달. (1.0a에서 추가된 검증 코드로 세션 고정 취약점 대응) 

  3. Access Token 교환 클라이언트가 요청 토큰 + oauth_verifier 로 서명 요청 → access_token + access_token_secret 수령.  

  4. 보호 자원 접근 이후 API 호출마다 access token/secret로 서명해 요청. 베어러 토큰이 아니라 매 요청 서명 검증이 핵심.

취약점

1.0의 경우 oauth_token + oauth_verifier 등의 정보를 Query parameter에 함께 전달하는데 이렇게 되면 브라우저 history에 남게 되어 탈취의 위험이 있었습니다.

또한, 일부 TLS 미사용 구현이 있어 탈취의 위험이 있었습니다.

이런 1.0의 세션 고정(session fixation) 문제를 막기 위해 1.0a에서 oauth_verifier 가 도입되었습니다.

OAuth 2.0의 과정

제 앱에서 Google 로그인 기능으로 로그인하는 상황을 가정해보겠습니다.

Google 로그인은 정확히는 OIDC(OpenID Connect) 프로토콜이고 OIDC 표준은 OAuth2.0 표준을 기반으로 하고 있습니다.

참여자

여기에서 주요 참여자는 총 4명입니다.

  • Client : 나의 앱

  • Resource Owner : 사용자

  • Resource Server: Google

  • (Authorization Server): Google (권한 서버)

OAuth 2.0 준비

Client가 Resource Owner(사용자)에게 권한을 요청하기 위해서는 먼저 OAuth2.0 프로토콜을 준비해야 합니다.

  1. Authorization Server에게 Client ID와 Client Secret을 발급받습니다.

  2. 요청 권한 Scope를 정의합니다.

  3. Redirect URI를 설정합니다.

AccessToken 발급 과정

  1. 사용자가 구글 로그인을 시도

  2. (로그인 되어 있지 않다면) 사용자가 구글 로그인

  3. 사용자가 승인을 마치면 Authorization Server 가 Redirect URI 로 authorization code 를 쿼리에 담아 사용자 에이전트(브라우저) 를 리디렉트

  4. 클라이언트(서버 백엔드)는 Authorization Server에 authorization code, client_id(+ client_secret, 해당 시), PKCE code_verifier(공개 클라이언트) 를 제출해 Access Token(± Refresh Token)을 발급

  5. 클라이언트는 발급받은 Access Token 으로 Resource Server(Google API)에 사용자 정보를 요청

  6. Client는 AccessToken을 사용하여 Resource Server에 접근하여 사용자 정보를 조회

  7. Client는 AccessToken이 만료되면 RefreshToken을 사용하여 AccessToken을 재발급

Bearer Token?

RFC 6750 - OAuth 2.0 Bearer Token Usage

Authorization 헤더에 보면 자주 Bearer <token> 형식으로 사용됩니다. 왜 굳이 Token 앞에 Bearer를 붙일까요?

RFC 6750 공식문서와 함께 알아보겠습니다.

RFC 6750이 왜 필요했을까?

해당 규약은 TLS 사용을 전제로 만들어진 토큰 전달과 사용 방법에 대한 구체적인 규약입니다.

  • HTTP 규약 준수 HTTP 표준에는 Authorization: <scheme> <credentials> 형식이 필요했는데, OAuth 토큰에 맞는 새로운 스킴을 만들어야 했습니다. OAuth 2.0에서 보안을 위해 Authorization 헤더를 사용하라고 정한 만큼 HTTP Authorization 헤더 규약을 맞출 필요가 있었습니다.

  • 토큰을 어떻게 싣고 전달해야하는가?에 대한 구체적인 정의 Access Token을 준다고는 되어있지만, 전달 후에 어떻게 사용해야하는지 정의되어 있지 않은데 이를 보강합니다.

Bearer 토큰이란?

Bearer 토큰은 “이 토큰을 소지한 어떤 주체(bearer)든, 다른 어떤 주체가 이 토큰을 가지고 사용할 수 있는 모든 방식으로 똑같이 사용할 수 있는” 성질을 가진 보안 토큰입니다.

즉, Bearer 토큰을 사용하는 데에는 암호학적 키 자료(Proof-of-Possession) 의 소유를 증명할 필요가 없습니다.

단순히 토큰을 가지고 있다는 사실만으로 접근 권한이 부여되는 소지자 기반 토큰입니다.

보안 리스크

소지자 기반 토큰인 만큼 탈취되면 그걸 가진 누구나 쓸 수 있어 주의가 필요합니다.

Reference

OAuth2.0 RFC 6749

OAuth1.0 RFC 5849

RFC 6750 - OAuth 2.0 Bearer Token Usage

생활코딩 OAuth2.0 유튜브

https://oauth.net/2/

https://blog.naver.com/mds_datasecurity/222182943542

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-OAuth-20-%EA%B0%9C%EB%85%90-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC

https://hudi.blog/oauth-2.0/

https://guide.ncloud-docs.com/docs/b2bpls-oauth2

More from this blog

SSM으로 private DB에 안전하게 연결

SSE를 통해 private DB를 외부에 노출하지 않고 접근할 수 있는 방법을 알아보겠습니다. private Instance에 접근하기 중요한 데이터와 비즈니스 로직이 들어있는 Instance들의 경우에는 보안을 위해 인터넷에 노출시키지 않고 사설망에 두고 운영하는 경우가 많습니다. 사설망에 있는 Instance들을 private Instance라고 합니다. 인터넷에 노출되지 않아 보안이 강력해지지만 관리자들도 접근할 수 없게되어 privat...

Sep 12, 20254 min read
SSM으로 private DB에 안전하게 연결

OIDC(OpenID Connect)

Google 로그인 등에 사용되는 OIDC(OpenID Connect)는 OAuth2.0 프로토콜을 기반으로 하고 있습니다. OAuth 2.0이 인증만 제공하는 반면, OIDC는 인증 기능을 추가하여 사용자 인증 및 인증 시나리오에 대한 보다 표준화된 솔루션을 제공합니다. 간단히 말해: OIDC = 인가 프로토콜 + 신원 인증 프로토콜 입니다. OIDC의 등장 배경 여러 서비스가 생겨나고 각 서비스는 각자 사용자 정보를 관리하게 됩니다. 하지만...

Sep 11, 20254 min read
OIDC(OpenID Connect)

PKCE & OAuth 2.1

기존의 OAuth 2.0을 보완하기 위한 여러 시도가 있습니다. 그 중 PKCE 그리고 더 발전된 형태인 OAuth 2.1에 대해 간략히 알아보겠습니다. PKCE (Proof Key for Code Exchange) PKCE는 악의적인 애플리케이션이 인증 코드를 가로채는 것을 방지하는 방법에 대한 내용입니다. OAuth 2.0 인증과정 중 Authorization code가 탈취 OAuth 2.0의 흐름 중 다음과 같은 과정이 있습니다. Re...

Sep 11, 20252 min read
PKCE & OAuth 2.1

관찰 가능성 시스템 구현기 2 - 구축과 적용

이번 포스팅에선 정의한 문제를 해결하기 위해 관찰 가능성 시스템을 구축하고 적용하기 위한 과정과 어떤 효과가 있었는지에 대해 공유하고자 합니다. 서론 일전엔 러프하게 Grafana 생태계를 고려한다고 했지만, 구체적으로 무엇을 어떻게 구현할지는 아직 정하지 않았으며 어떤 인프라를 이용해 구현할지도 아직 정하지 않았습니다. 구체적인 선택의 과정과 구현 과정을 공유하고자 합니다. 또한, 이 완성된 시스템이 조직의 논의를 통해 점진적으로 적용되는 과...

Sep 9, 20255 min read
관찰 가능성 시스템 구현기 2 - 구축과 적용
K

KyungJun Woo | Software Engineer

30 posts