기존의 전통적인 클라이언트-서버 인증 방식에서는 클라이언트가 서버에 접근이 제한된 자원(보호된 자원)을 요청하고 사용자의 자격 증명(ID, 비밀번호)으로 서버에 인증을 해서 접근한다.
만약 외부(타사) 애플리케이션이 이런 제한된 자원에 접근하게 하려면 사용자가 자신의 ID/비밀번호를 그 외부 앱에 직접 알려줘야한다.
이 방식은 여러 문제점과 한계를 만든다.
조금 쉽게 말하면 기존 방식은 내 아이디랑 비밀번호 줄테니까 대신 로그인해서 써라는 구조 였는데 Oauth는 비밀번호는 절대 주지 말고 이 범위까지만 쓸 수 있는 임시 출입증(토큰)을 줄게 라는 발상에서 나옴
문제점 및 한계점
1. 타사 애플리케이션은 나중에 다시 사용하기 위해 리소스 소유자의 자격 증명, 보통은 비밀 번호 평문(clear-text) 형태로 저장
즉, 외부 앱 서버에 내 비밀번호가 그대로 저장됨
2. 서버는 비밀번호 자체가 본질적으로 보안에 취약하다는 사실을 알면서도 비밀번호 인증 방식을 계속 지원해야했음.
3. 타사 애플리케이션은 사용자의 보호된 리소스에 대해 지나치게 광범위한 접근 권한을 얻게 되며, 사용자는 접근 기간을 제한하거나, 일부 리소스만 허용할 수 없다.
사진만 허용 같은 세밀한 제어가 불가능
4. 사용자는 특정 하나의 타사 애플리케이션만 접근 권한을 취소할 수 없고 모든 타사의 접근을 끊으려면 비밀번호를 변경해야함
5. 어느 하나의 애플리케이션이라도 해킹되면, 사용자의 비밀번호가 유출되고 그 비밀번호로 보호되던 모든 데이터가 함께 노출된다.
OAuth는 권한 부여 계층을 도입하고 클라이언트와 리소스 소유자의 역할을 분리함으로써 이러한 문제를 해결한다.
OAuth에서 클라이언트는 리소스 소유자가 관리하고 리소스 서버에서 호스팅하는 리소스에 대한 접근을 요청하고, 리소스 소유자와는 다른 자격 증명 세트를 발급받는다.
OAuth는 사용자의 ID/비밀번호를 쓰지 않고 클라이언트는 액세스 토큰을 받는다.
- 이 토큰은 어떤 권한, 얼마나 유효한지, 기타 접근 조건을 담고 있는 문자열이다.
- 토큰은 사용자의 동의를 받아 인가 서버가 타사 클라이언트에게 발급한다. 클라이언트는 이 토큰으로 보호된 자원에 접근한다. 그 자원은 리소스 서버에 있다.
예를 들어 최종 사용자(리소스 오너)는 사진 공유 서비스(리소스 서버)에 저장된 자신의 보호된 사진들에 대해 인쇄 서비스(클라이언특)가 접근할 수 있도록 허용할 수 있다. 이때 사용자는 인쇄 서비스에 자신의 사용자 이름이나 비밀번호를 공유하지 않는다. 대신, 사용자는 사진 공유 서비스가 신뢰하는 서버(인가 서버)에 직접 인증을 수행하고, 그 서버는 인쇄 서비스에 위임 전용 자격 증명 즉, 액세스 토큰을 발급한다.
사진 공유 서비스는 리소스 서버라고 보면 되는데 인쇄 서비스가 타사 애플리케이션이라고 보면 된다.
사진 공유 서비스에 연결된 사용자가 있고 그 사진을 인쇄해주는 다른 서비스가 있다. 이때 사진 공유 서비스가 토큰을 만들어서 인쇄 서비스에게 임시로 접근 자격을 부여
이 사양은 HTTp(RFC 2616)와 함께 사용되도록 설계되었다. HTTP가 아닌 다른 프로토콜 위에서 OAuth는 사용하지 못한다.
OAuth 1.0 프로토콜은 소규모 임시 커뮤니티의 노력으로 탄생함. OAuth 1.0과 IETF 커뮤니티 노력해서 OAuth 2.0 나옴 하지만 OAuth 1.0과 호환되지는 않는다. 두 버전은 네트워크에서 공존할 수 있다. 그러나 두 버전은 같은 환경에서 함께 존재할 수 있고 필요하다면 하나의 시스템이 두 버전을 모두 지원할 수도 있다. 하지만 이 문서의 분명한 의도는 다음과 같다. 새로 만드는 서비스는 OAuth 2.0을 사용하고 OAuth 1.0은 이미 운영 중인 옛 시스템을 유지하는 데에만 사용하라는 것이다. 또한 OAuth 2.0은 OAuth 1.0과 구현 방식이 거의 완전히 다르다. 그래서 OAuth 1.0에 익숙한 개발자라 하더라도 “비슷할 것이다”라고 가정하지 말고 완전히 새로운 프로토콜로 다시 배워야 한다.
1.1 역할(Roles)
OAuth는 다음과 같은 4가지 역할을 정의
1. 리소스 소유자
- 보호된 자원에 대한 접근 권한을 줄 수 있는 주체
보통은 사람(사용자)
2. 리소스 서버
- 액세스 토큰을 받아서 유효하면 요청을 처리하고 아니면 거부
액세스 토큰을 받아서 유효하면 요청을 처리하고 아니면 거부
3. 클라이언트
- 사용자를 대신해서 보호된 자원을 요청하는 애플리케이션
- 반드시 사용자의 허락을 받아야함, 클라이언트라는 말은 서버인지 웹인지 모바일인지 아무것도 가정하지 않는다.
4. 인가 서버
- 사용자를 인증하고, 동의를 받은 뒤 토큰을 발급하는 서버
- 사용자 로그인처리, 이 앱이 권한을 써도 되나요? 동의 처리, 승인되면 access token 발급
리소스 사용자는 사용자
리소스 서버는 카카오라고 한다면 카카오 프로필, 이메일, 친구 목록을 가진 서버를 말함
클라이언트는 우리가 만든 서버
인가 서버는 카카오 인증 및 토큰 발급 역할을 하는 서버
이 문서에서 인가 서버와 리소스 서버가 서로 어떻게 통신하는지까지는 다루지 않는다. 즉, 두 서버가 내부적으로 토큰을 어떻게 확인하고 공유하는지는 각 서비스가 알아서 설계하면 된다.
인가 서버와 리소스 서버는 같은 서버일수도 있고, 완전히 분리된 서로 다른 서버일 수도 있다. 또한, 하나의 인가 서버가 여러 개의 리소스 서버에서 공통으로 사용할 수 있는 액세스 토큰을 발급할 수도 있다.
1.2 프로토콜 흐름

그림 1에 나타낸 추상적인 OAuth 2.0 흐름은 네 가지 역할 간의 상호 작용을 설명하며 다음과 같은 단계를 포함한다.
(A) 클라이언트는 리소스 소유자에게 권한 부여를 요청. 권한 부여 요청은 리소스 소유자에게 직접 (그림과 같이) 또는 (가급적이면) 권한 부여 서버를 통해 간접적으로 수행할 수 있습니다.
(B) 클라이언트는 권한 부여 부여(authorization grant)를 수신합니다. 이는 리소스 소유자의 권한을 나타내는 자격 증명으로, 이 명세에 정의된 네 가지 부여 유형 중 하나 또는 확장 부여 유형을 사용하여 표현됩니다. 권한 부여 부여 유형은 클라이언트가 권한을 요청하는 데 사용한 방법과 권한 부여 서버에서 지원하는 유형에 따라 달라집니다.
여기서 말하는 4가지 유형은 밑 1.3 권한 부여 방식에서 공부하게 된다.
(C) 클라이언트는 권한 부여 서버에 인증하고 권한 부여 부여를 제시하여 액세스 토큰을 요청합니다.
(D) 권한 부여 서버는 클라이언트를 인증하고 권한 부여를 검증하며, 유효한 경우 액세스 토큰을 발급합니다.
(E) 클라이언트는 리소스 서버에 보호된 리소스를 요청하고 액세스 토큰을 제시하여 인증합니다.
(F) 리소스 서버는 액세스 토큰을 검증하고, 유효한 경우 요청을 처리합니다. 클라이언트가 리소스 소유자로부터 권한 부여를 얻는 데 선호되는 방법(단계 (A) 및 (B)에 설명됨)은 권한 부여 서버를 중개자로 사용하는 것이며 이는 섹션 4.1의 그림 3에 설명되어 있습니다.
1.3. 권한 부여 방식(Authorization Grant)
권한 부여는 클라이언트가 액세스 토큰을 얻기 위해 사용하는 리소스 소유자의 권한(보호된 리소스에 접근할 수 있는 권한)을 나타내는 자격 증명이다. 이 사양에서 권한 부여 코드, 암시적, 리소스 소유자 암호 자격 증명 및 클라이언트 자격 증명의 4가지 부여 유형과 추가 유형을 한 번 알아보자
사용자 동의가 끝난 결과로 사용자의 허락을 나타내는 값을 클라이언트(우리 서버)가 받는다. 그 값이 이 4가지 중 하나라는 것 그러면 사용자의 허락을 나타내는 값을 클라이언트가 인가 서버에 제출하여 액세스 토큰으로 교환하는 형태

즉, 이 부분을 말하는데 인가 승인 정보란 사용자가 자신의 보호된 자원에 접근해도 된다고 허락했다는 증거다.
이 허락 증거를 이용해서 인가 서버로부터 액세스 토큰을 받는다. 이 문서에서는 이런 허락 증거를 전달하는 방식으로 4가지 방법을 정의
- 인가 코드 방식
- Implicit 방식
- 사용자 비밀번호 방식
- 클라이언트 자격 증명 방식
그리고 이 4가지 말고도 필요하다면 새로운 방식들을 추가로 정의할 수 있도록 확장 방법도 함꼐 제공 C단계에서 사용되는 인가 승인 정보를 얻는 방식이 4가지라는 거
1.3.1 인가 코드(Authorization Code)
우리 서비스(클라이언트)는 카카오 계정으로 로그인하고 싶다고 생각한다. 그런데 우리 서비스는 사용자에게 아이디 및 비밀번호를 직접 달라고 하지 않는다. 대신 우리 서비스는 사용자를 카카오 로그인 페이지로 보내준다. 사용자는 카카오 페이지에서 직접 로그인하고 이 앱이 내 정보 써도 된다는 동의 버튼을 누른다. 그러면 카카오는 이 사용자가 이 앱을 허락했다는 뜻의 짧은 번호표(인가 코드)를 만들어서 사용자를 다시 우리 서비스로 돌려보낸다. 우리 서비스는 그 번호표를 카카오에게 보여주고 진짜 출입증(액세스 토큰)을 받는다.
인가 코드는 두 가지 중요한 보안 장점이 있다.
1. 클라이언트가 진짜 자기 자신인지 확인할 수 있다.
- 인가 코드를 토큰으로 바꿀 때 클라이언트는 자기 신분(client_id/client_secret)을 함께 제시
- 그래서 인가 서버는 이 요청이 진짜 이 앱에서 온 게 맞는지 확인 가능
가짜 앱이 토큰을 가로채 쓰기 어려움
2. 액세스 토큰이 사용자 브라우저를 거치지 않는다.
- 인가 코드는 브라우저를 통해 전달되지만 진짜 중요한 액세스 토큰은 인가 서버 -> 클라이언트 서버로 직접 전달된다.
브라우저 주소창, 로그, 히스토리, 사용자 본인에게 토큰이 노출될 가능성이 크게 줄어든다.
'RFC > OAuth 2.0' 카테고리의 다른 글
| [OAuth 2.0] Abstract, Status of This Memo, Copyright Notice (1) | 2025.12.20 |
|---|
