OAuth란 무엇인가?
인증을 넘겨보자
OAuth란 무엇인가?
OAuth(Open Authorization)는 제3자 애플리케이션이 리소스 소유자(사용자)를 대신해 리소스 서버(API)에 접근할 수 있도록 권한을 위임하는 인증 프로토콜이다.
주요 특징:
- 비밀번호를 직접 전달하지 않고도 사용자 권한을 위임할 수 있다
- 접근 토큰(Access Token)을 통해 자원 접근을 제어한다
- 인증(Authentication)과 권한 위임(Authorization)을 분리한다
OAuth 1.0과 2.0의 차이점
OAuth 2.0은 더 유연하고 다양한 사용 시나리오(웹, 모바일, API 등)를 고려한 현대적인 인증 프로토콜이다. 현재는 거의 대부분 OAuth 2.0이 표준으로 사용된다.
왜 OAuth가 필요한가?
구글 계정으로 로그인하는 소셜 로그인을 생각해보면, 다른 사이트에 내 비밀번호를 그대로 입력하는 순간 노출 위험이 생긴다. OAuth는 비밀번호 대신 토큰으로 권한을 위임해서 이 문제를 없앤다.
외부 시스템이 내 API를 호출하는 경우도 마찬가지다. API 키 하나만으로는 "읽기만 허용"처럼 세분화된 권한 제어가 어렵지만, 토큰에 권한 범위(Scope)를 붙이면 자원별로 정밀하게 제어할 수 있다.
토큰이 만료될 때마다 사용자에게 다시 로그인을 요구하면 불편이 쌓이는데, 재발급 토큰(Refresh Token)으로 뒤에서 조용히 갱신하면 사용자 경험도 지킬 수 있다.
주요 용어 정리
그림의 용어를 한 줄씩 풀면 이렇다. 리소스 소유자(Resource Owner)는 리소스를 가진 사용자, 클라이언트(Client)는 그 리소스를 요청하는 제3자 앱(예: 내 서비스)이다. 인가 서버(Authorization Server)는 인증을 담당하며 토큰을 발급하고, 리소스 서버(Resource Server)는 토큰을 검증한 뒤 보호된 리소스를 내어준다. 접근 토큰(Access Token)은 인증이 끝난 뒤 발급되는 자원 접근용 토큰이고, 재발급 토큰(Refresh Token)은 접근 토큰이 만료됐을 때 재발급을 요청하는 용도다. 권한 범위(Scope)는 접근 토큰이 어디까지 접근할 수 있는지를 정한 값이다.
OAuth 2.0 인증 흐름 (Authorization Code Flow)
AuthServer: 승인 AuthServer-->>ClientApp: Authorization Code ClientApp->>AuthServer: Authorization Code 교환 (client_secret 포함) AuthServer-->>ClientApp: Access Token (+ Refresh Token) ClientApp->>ResourceServer: API 요청 (Authorization: Bearer token) ResourceServer-->>ClientApp: 응답 데이터 -->
인가 서버가 접근 토큰을 바로 주지 않고 인가 코드(Authorization Code)라는 교환권을 먼저 발급하는 점이 핵심이다. 클라이언트는 이 코드를 서버만 아는 값인 client_secret과 함께 제출해야 토큰을 받을 수 있다.
이 흐름은 사용자가 브라우저에서 로그인하는 구조로, 보안상 가장 권장되는 방식이다.
Scope의 활용
OAuth에서 권한 범위(Scope)는 "접근 토큰이 어떤 리소스에 어떤 수준으로 접근 가능한지"를 지정한다. 예를 들어 profile은 사용자 이름 같은 기본 프로필 조회 권한, email은 이메일 주소 접근 권한이다. read:posts처럼 게시글 읽기 전용 권한과 write:posts처럼 작성·수정 권한을 갈라두면, 읽기만 필요한 앱에 쓰기 권한까지 내줄 일이 없어진다.
권한 범위를 세분화하면 리소스별 접근 제어를 정밀하게 설정할 수 있고, 사용자로부터 명확한 동의를 받는 UX도 가능해진다.
Access Token과 Refresh Token 저장 및 관리 전략
- 접근 토큰은 만료시간을 짧게 잡는다(5~30분). 유출되더라도 쓸 수 있는 시간을 줄이기 위해서다.
- 재발급 토큰은 HttpOnly 쿠키, 즉 자바스크립트로는 읽을 수 없는 쿠키로 보관한다.
- 만료 시에는 사용자 모르게 자동으로 재요청한다(silent refresh).
백엔드를 통한 안전한 인증 구조
서버 투 서버(Server-to-Server) 방식이 안전한 이유
OAuth 인증 흐름에서 클라이언트(프론트엔드)가 직접 인가 서버와 통신하는 구조는 간단하지만 보안 및 유연성 측면에서 단점이 많다. 반면 서버 → 서버 간 통신 구조는 아래와 같은 이유로 실무에서 더 안전하고 확장성 있는 방식으로 채택된다.
먼저 보안 측면이다. client_secret이나 재발급 토큰 같은 민감한 값은 서버에만 보관해 노출을 막을 수 있고, 서버 내부 통신은 TLS로 인증된 안전한 채널을 쓰기 때문에 중간자 공격 방지에도 유리하다. 웹 방화벽(WAF), 요청 횟수 제한, 로그 기록, IP 제한 같은 서버 측 보안 정책도 한 곳에서 적용할 수 있다.
운영 측면의 이점도 크다. 접근 토큰이 만료되면 서버가 자동으로 갱신을 처리할 수 있고(silent refresh), 인증 후 유저 정보를 받아 DB 저장·권한 부여·마케팅 수신 동의 같은 추가 처리를 끼워 넣기도 쉽다. 인증 상태는 JWT(JSON Web Token) 또는 세션 방식으로 통합 관리할 수 있어 로그아웃이나 강제 만료 처리가 한 곳에서 끝난다. 구글, 카카오처럼 인증 제공자가 여러 개여도 인증 흐름을 하나의 인터페이스로 정리할 수 있다.
실전에서는 보통 프론트엔드에서 로그인 버튼 클릭 → 백엔드에서 OAuth 인증 요청 생성 → 인증 완료 후 토큰 수신 및 유저 등록까지 한 번에 처리하는 구조를 사용한다.
프론트-백엔드-OAuth 연동 흐름
BE: Access Token (Refresh Token 포함) BE->>RS: Resource 요청 (with Access Token) RS-->>BE: 응답 BE-->>FE: 응답 전달 -->
실전 노하우 모음
- 토큰 저장 — 접근 토큰과 재발급 토큰 모두 서버에 저장하고 관리하는 구조를 권장한다. 프론트엔드는 토큰을 직접 보관하지 않고, 인증 상태는 서버가 책임진다.
- 토큰 갱신 — 접근 토큰이 만료되면 백엔드에서 자동 갱신 처리한다(silent refresh). 재발급 토큰은 DB나 인메모리 같은 서버 내 안전한 저장소에 보관한다.
- 로그인 연동 — 최초 로그인 시 OAuth 프로필을 기반으로 유저 테이블을 생성하거나 매핑한다.
- 상태 관리 — 인증 상태는 서버 세션 혹은 자체 JWT 기반으로 통합 관리한다. 프론트는
/meAPI 응답 같은 걸로 인증 유무만 판단한다. - 로그아웃 처리 — 접근 토큰과 재발급 토큰 모두 서버에서 무효화하고, 세션 삭제와 쿠키 제거까지 한 세트로 처리한다.
서버-투-서버 구조에서는 브라우저의 LocalStorage나 SessionStorage를 사용하지 않으며,
모든 민감한 인증 정보는 서버가 책임지고 관리해야 한다.
마무리
OAuth는 단순한 인증 수단이 아니라 서비스의 보안성과 사용자 경험을 동시에 고려해야 하는 핵심 인프라다.
직접 OAuth 서버를 운영하거나, Google/Kakao 등 외부 인증 시스템을 연동할 때도 위 구조와 보안 전략을 고려한다면 안정적이고 유지보수 쉬운 인증 시스템을 설계할 수 있다.