1. OAuth2 개념과 동작 흐름

오늘날 서비스들은 외부 애플리케이션과 데이터를 안전하게 공유해야 하는 상황이 많습니다. 예를 들어, 구글 계정으로 다른 웹사이트에 로그인하거나, 카카오 계정으로 쇼핑몰에 접속하는 것처럼 하나의 서비스에서 발급받은 자격 증명으로 다른 서비스의 자원에 접근하는 경우가 대표적입니다.

이 과정에서 가장 중요한 것은 보안입니다. 단순히 아이디와 비밀번호를 공유하는 방식은 여러 문제를 야기하기 때문에, 이를 해결하기 위해 등장한 표준 프로토콜이 바로 OAuth 2.0입니다.


1.1 OAuth2가 필요한 이유

기존 클라이언트-서버 인증 모델에서는 클라이언트가 서버의 보호 자원(protected resource)에 접근할 때, 자원 소유자의 ID/비밀번호(자격 증명)로 서버에 인증했습니다.

그러나 제3자 애플리케이션(third-party application)이 보호 자원에 접근하려면, 사용자가 자신의 자격 증명을 직접 공유해야 했습니다.

이 경우 제3자 애플리케이션은 자격 증명을 보관해야 했고, 대부분 평문 비밀번호로 저장하는 위험한 구조를 가졌습니다. <br><br>

🔎 시나리오 예시

  1. A캘린더 앱(제3자 애플리케이션)은 사용자의 구글 캘린더 정보를 가져오고 싶다.
  2. 하지만 구글 캘린더 정보는 사용자 본인만 접근할 수 있다.
  3. 따라서 A캘린더 앱은 사용자의 ID/비밀번호를 받아 직접 구글 서버에 접근해야 한다.

👉 결과적으로 사용자는 자신의 비밀번호를 제3자에게 그대로 넘겨주게 된다.


문제점

번호문제
1서버는 비밀번호 인증을 지원해야 하며, 비밀번호 자체의 보안 취약성을 피할 수 없다.
2제3자 애플리케이션은 사용자의 모든 자원에 접근할 수 있어, 범위/기간 제한이 불가능하다.
3특정 제3자의 접근만 취소할 방법이 없어, 결국 비밀번호 전체를 변경해야 한다.
4제3자 애플리케이션이 침해되면, 사용자의 비밀번호와 그 비밀번호로 보호된 모든 데이터가 노출된다.

OAuth의 해결책

OAuth는 비밀번호를 제3자에게 직접 넘겨주는 위험한 방식을 없애고, 인가 서버(Authorization Server)가 발급한 액세스 토큰(access token)을 통해 필요한 범위(scope)만 위임하는 방식을 제공합니다.

👉 즉, 사용자는 비밀번호 대신 토큰으로 제3자에게 권한을 위임할 수 있습니다.


1.2 주요 용어와 역할

  1. Resource Owner
    • 보호된 자원에 대한 접근을 허용할 수 있는 주체.
    • 자원 소유자가 사람일 경우 end-user(최종 사용자)라고 부른다.
  2. Resource Server
    • 보호된 자원을 호스팅하는 서버.
    • 액세스 토큰을 사용해 들어오는 보호된 자원 요청을 받아들이고 응답할 수 있다.
  3. Client
    • 자원 소유자를 대신하여, 그리고 자원 소유자의 인가를 받아 보호된 자원을 요청하는 애플리케이션.
  4. Authorization Server
    • 자원 소유자를 성공적으로 인증하고 인가를 받은 뒤, 클라이언트에게 액세스 토큰을 발급하는 서버.

각 역할은 아래의 관계를 가집니다.

image


1.3 Authrization Code를 이용한 Authrization Grant 과정

OAuth 2.0에서 Authorization Grant는 클라이언트가 액세스 토큰(access token)을 얻기 위해 사용하는 자격 증명(credential)을 의미합니다. 즉, 자원 소유자가 자신의 보호된 자원에 접근할 수 있도록 허용한 인가(authorization)를 표현하는 것입니다.

Authorization Grant 방식에는 여러 가지가 있지만, 대부분의 플랫폼에서는 Authorization Code 방식을 사용합니다.


1.3.1 Authorization Code 방식이란?

Authorization Code 방식은 클라이언트와 자원 소유자 사이에 인가 서버(Authorization Server)를 중개자로 두는 구조입니다. Authorization Code는 아래의 과정으로 진행됩니다.

  • 클라이언트가 직접 자원 소유자에게 인가를 요청하지 않습니다.
  • 대신 자원 소유자를 인가 서버로 리다이렉트(redirect) 합니다.
  • 인가 서버는 자원 소유자를 다시 클라이언트로 리다이렉트하면서 인가 코드(authorization code)를 전달합니다.

이 과정을 통해 클라이언트는 인가 코드를 획득하고, 이를 이용해 인가 서버에 액세스 토큰을 요청하게 됩니다.


Authorization Code 방식의 장점

  1. 보안성 강화
    • 액세스 토큰이 사용자 브라우저나 사용자에게 직접 노출되지 않기 때문에 안전합니다.
  2. 사용자 자격 증명 보호
    • 클라이언트는 사용자의 아이디·비밀번호를 직접 알 필요가 없습니다.
  3. 광범위한 활용성
    • 웹 애플리케이션과 모바일 애플리케이션을 포함해, 오늘날 대부분의 서비스에서 표준적으로 사용됩니다.

👉 정리하자면, Authorization Code 방식은 OAuth 2.0에서 가장 널리 쓰이는 인가 승인 방식으로, 사용자 정보를 보호하면서도 클라이언트가 안전하게 액세스 토큰을 받을 수 있는 구조입니다.


2. 토큰 이해하기

OAuth 2.0에서 가장 핵심적인 개념은 바로 토큰(Token)입니다.

OAuth는 사용자의 아이디와 비밀번호 같은 민감한 정보를 직접 다루지 않고, 토큰이라는 매개체를 통해 인증과 인가를 처리합니다.

토큰은 말 그대로 열쇠(key) 역할을 합니다.

  • 어떤 토큰은 자원 서버에 직접 접근할 때 쓰는 열쇠이고,
  • 또 다른 토큰은 새로운 열쇠를 만들어내는 예비 열쇠 역할을 합니다.

이처럼 토큰은 OAuth의 모든 흐름을 연결하는 핵심 요소이기 때문에, 이제부터는 두 가지 주요 토큰인 Access Token과 Refresh Token에 대해 차례대로 알아보겠습니다.


2.1 Access Token이란?

Access Token(액세스 토큰)은 클라이언트가 보호된 자원(protected resource)에 접근하기 위해 사용하는 자격 증명(credential)입니다. 이는 인가 서버(Authorization Server)가 클라이언트에게 발급하는 문자열(string)이며, 보통 클라이언트 입장에서는 내부 구조를 알 수 없는 불투명(opaque) 값으로 취급됩니다.


Access Token의 특징

  • 권한 표현: 토큰은 특정 범위(scope)와 유효 기간(duration)을 나타내며, 이는 자원 소유자가 허용하고 서버가 강제합니다.
  • 형태:
    • 단순히 인가 정보를 조회하기 위한 식별자(identifier)일 수 있고,
    • 또는 인가 정보를 자체적으로 포함하는 JWT(JSON Web Token) 형태일 수도 있습니다.
    • 추가 인증: 경우에 따라 클라이언트가 토큰을 사용할 때 추가 인증 수단이 요구될 수도 있습니다.

Access Token의 역할

액세스 토큰은 인증 추상화 계층을 제공합니다. 즉, 다양한 인증 방식(아이디/비밀번호, API 키 등)을 하나의 토큰 기반 인증 방식으로 단순화합니다.

이를 통해 얻을 수 있는 장점은 다음과 같습니다:

  1. 보안성: 토큰 발급 시 원래의 인가 승인(Authorization Grant)보다 더 제한적인 권한만 부여할 수 있습니다.
  2. 단순화: 자원 서버는 다양한 인증 방식을 이해할 필요 없이, 토큰만 검증하면 됩니다.

👉 정리하자면 Access Token은 사용자의 인가를 표현하는 문자열로, 자원 서버와 인가 서버가 공통으로 이해할 수 있는 표준화된 인증 수단입니다. 이를 통해 보안성과 단순성을 동시에 확보할 수 있습니다.


2.2 Refresh Token이란?

Refresh Token(리프레시 토큰)은 새로운 Access Token을 발급받기 위해 사용하는 자격 증명입니다.

즉, 한 번 로그인했다고 해서 무기한 Access Token을 쓰는 게 아니라, Access Token이 만료되었을 때 다시 로그인할 필요 없이 Refresh Token으로 새로운 Access Token을 발급받는 것입니다.


Refresh Token의 특징

  • Access Token 갱신용 입니다.
  • 현재 Access Token이 만료되거나 더 이상 유효하지 않을 때, 새로운 Access Token을 발급받는 데 사용됩니다.
  • Refresh Token을 통해 얻는 Access Token은 보통 동일하거나 더 좁은 권한(scope)을 가집니다.
  • 모든 서비스가 Refresh Token을 주는 건 아닙니다.
  • 인가 서버(Authorization Server)의 정책에 따라 발급 여부가 결정됩니다.
  • 클라이언트 전용
  • Refresh Token은 오직 인가 서버(Authorization Server)와 통신할 때만 사용됩니다.
  • 자원 서버(Resource Server)에는 절대 전달되지 않습니다.

Refresh Token의 구조

  • Refresh Token은 클라이언트가 직접 내용을 알 수 없는 불투명한 문자열(opaque string)입니다.
  • 내부적으로는 인가 정보를 조회할 수 있는 식별자 역할을 합니다.

왜 Refresh Token이 중요한가?

  1. 보안성
    • Access Token은 수명이 짧아서 만료되면 무용지물이 됩니다.
    • Refresh Token이 있으면, 재로그인 없이도 안전하게 새로운 Access Token을 받을 수 있습니다.
  2. 사용자 편의성
    • 사용자가 매번 로그인할 필요가 없으니 UX가 좋아집니다.
  3. 서버 제어력 강화
    • 서버는 Refresh Token을 무효화시켜 특정 사용자의 세션만 종료할 수 있습니다.
    • 반면 Access Token만 있다면, 유효기간이 끝날 때까지 막기 어렵습니다.

<br> 👉 정리하자면 Refresh Token은 Access Token의 수명 문제를 해결해주는 보완재입니다.

클라이언트는 Refresh Token을 보관해두었다가 Access Token이 만료되면 새 토큰을 발급받고, 사용자는 끊김 없는 서비스 경험을 누릴 수 있습니다.


2.3 Access Token vs Refresh Token

구분Access TokenRefresh Token
역할보호된 자원에 직접 접근하기 위한 인증 수단새로운 Access Token을 발급받기 위한 인증 수단
수명짧음 (분~수십 분)긺 (보통 며칠~수개월)
사용처자원 서버(Resource Server)에 전달인가 서버(Authorization Server)에만 전달
발급 시점로그인/인가 성공 시 발급Access Token 발급 시 함께 발급될 수 있음 (선택 사항)
보안 위험탈취 시 즉시 자원 접근 가능 → 짧은 만료 시간으로 완화탈취 시 새로운 Access Token 발급 가능 → 안전한 저장이 필수
사용자 경험만료되면 재로그인 필요재로그인 없이 새로운 Access Token 발급 가능
예시“열쇠” (자원 서버 문을 여는 열쇠)“예비 열쇠” (새 열쇠를 만들 수 있는 열쇠)

2.4 Refresh Token을 사용해야 하는 이유

결론적으로, Refresh Token을 사용하면 인가에 필요한 민감한 키를 최소한으로 전송하면서 탈취 위험을 낮출 수 있습니다.


Access Token만 사용할 경우의 문제

만약 Access Token만 존재한다고 가정해보겠습니다.

  • 클라이언트는 Access Token으로 로그인 인증과 데이터 접근 권한을 얻습니다.
  • 사용자의 편의를 위해 Access Token의 만료 시간을 3개월로 설정했다고 합시다.
  • 이때 공격자가 Access Token을 탈취하면, 공격자는 해당 기간 동안 사용자의 정보에 자유롭게 접근할 수 있습니다.

👉 즉, Access Token만 장기간 유지되는 구조는 보안상 매우 위험합니다.


Access Token과 Refresh Token의 역할 분리

이 문제를 해결하기 위해 OAuth2는 두 가지 토큰을 도입했습니다.

  1. Access Token
    • 보호된 자원에 접근할 때 사용하는 토큰
    • API 요청 시마다 사용되므로 자주 노출될 수 있음
    • 만료 기간을 짧게 설정해 탈취되더라도 피해를 최소화

<br>

  1. Refresh Token
    • 새로운 Access Token을 발급받기 위한 토큰
    • 클라이언트 내부에 안전하게 보관되며, 외부 요청에는 거의 노출되지 않음
    • 통상적으로 6~12개월의 긴 만료 기간을 가짐
    • 비정상적인 요청이 감지되면 서버 측에서 Refresh Token을 폐기할 수도 있음

동작 방식

  • Access Token이 만료되면, 클라이언트는 기존에 보관 중이던 Refresh Token을 인가 서버에 전달합니다.
  • 인가 서버는 이를 검증한 뒤 새로운 Access Token을 발급합니다.

OAuth2에서의 Access Token, Refresh Token의 발급 과정


Access Token을 Refresh Token처럼 서버에 보관하지 않는 이유

그렇다면 "Access Token도 서버(DB/Redis)에 보관해두고, 탈취가 의심되면 교체하면 되지 않을까?"라는 생각을 할 수 있게 됩니다. 하지만 Access Token의 만료 기간을 길게 설정하여 Refresh Token 처럼 사용하게 되면 아래와 같은 문제가 발생할 수 있습니다.

서버에 보관하는 방식의 문제점

  • 모든 Access Token을 서버(DB/Redis)에 저장하면, 대규모 서비스에서 토큰 조회/검증 부담이 커짐.
  • 특히 글로벌 서비스에서 매 요청마다 서버 스토리지를 조회해야 한다면 성능 저하.
  • 서버 저장소를 쓰면 Stateless가 깨지고, 분산 환경에서 관리 포인트가 늘어남.
  • 실질적 보안 이득 적음.

👉 결국, Access Token과 Refresh Token을 분리해 사용하는 구조가 보안성과 효율성을 동시에 확보하는 가장 합리적인 방법입니다.


다음 게시물에선 Spring을 이용한 Kakao OAuth2 로그인 구현 방법에 대해 설명하겠습니다. 감사합니다~!


참고