OAuth 2.0
한눈에 보기
OAuth 2.0은 비밀번호를 제3자 앱에 넘기지 않고 자원 접근 권한을 위임하는 인가 표준 프로토콜이다. 네 가지 역할과 인가 코드 그랜트 흐름, PKCE, OIDC와의 차이, 구현 시 보안 유의점을 깊게 다룬다.
최종 업데이트 2026.09.17
OAuth 2.0은 사용자가 자신의 비밀번호를 제3자 애플리케이션에 넘기지 않고도, 자신이 가진 자원에 대한 접근 권한을 그 애플리케이션에 위임(Delegation)할 수 있게 하는 인가(Authorization) 표준 프로토콜이다. 예를 들어 일정 관리 앱이 구글 캘린더를 읽어야 할 때, 사용자는 구글에 직접 로그인해 동의만 하고 앱은 구글이 발급한 액세스 토큰(Access Token)으로 캘린더 API에 접근한다. OAuth의 본질은 로그인 기능이 아니라 권한 위임이며, 이 구분이 면접에서 가장 자주 검증되는 지점이다.
네 가지 역할
OAuth 2.0은 참여자를 네 역할로 나눈다. 자원 소유자(Resource Owner)는 데이터의 주인인 사용자다. 클라이언트(Client)는 사용자의 자원에 접근하려는 제3자 애플리케이션이다. 인가 서버(Authorization Server)는 사용자를 인증하고 동의를 받아 토큰을 발급하는 서버로, 구글 계정 서버가 그 예다. 자원 서버(Resource Server)는 보호된 데이터를 실제로 제공하는 API 서버로, 구글 캘린더 API가 해당한다. 클라이언트는 사전에 인가 서버에 등록해 클라이언트 아이디(Client ID)와 클라이언트 시크릿(Client Secret)을 받아 두며, 토큰이 허용하는 접근 범위는 스코프(Scope)로 명시된다. 스코프 덕분에 사용자는 캘린더 읽기만 허용하고 수정은 막는 식의 세밀한 위임이 가능하다.
인가 코드 그랜트의 흐름
여러 흐름(Grant) 중 표준으로 권장되는 것은 인가 코드 그랜트(Authorization Code Grant)다. 단계는 다음과 같다.
- 사용자가 클라이언트 앱에서 구글로 연동하기를 누르면, 앱은 클라이언트 아이디, 스코프, 리다이렉트 URI(Redirect URI), 위조 방지용 state 값을 붙여 인가 서버의 동의 화면으로 사용자를 보낸다.
- 사용자는 인가 서버에서 직접 로그인하고 요청된 권한 범위에 동의한다. 비밀번호는 인가 서버에만 입력된다.
- 인가 서버가 사용자를 등록된 리다이렉트 URI로 돌려보내며, 짧은 수명의 일회용 인가 코드(Authorization Code)를 쿼리로 전달한다.
- 클라이언트의 백엔드가 이 코드와 클라이언트 시크릿을 인가 서버의 토큰 엔드포인트에 제출해 액세스 토큰으로 교환한다. 이 통신은 브라우저를 거치지 않는 서버 간 통신이다.
- 클라이언트는 액세스 토큰을 Authorization 헤더에 담아 자원 서버 API를 호출하고, 자원 서버는 토큰의 유효성과 스코프를 확인한 뒤 데이터를 내준다.
GET /calendar/v3/events HTTP/1.1
Host: api.example.com
Authorization: Bearer ya29.a0AfH6...
코드 교환 단계를 굳이 두는 이유는 토큰이 브라우저 주소창과 히스토리에 노출되는 것을 막고, 시크릿을 아는 진짜 클라이언트만 토큰을 얻게 하기 위해서다. 액세스 토큰이 만료되면 함께 발급된 리프레시 토큰(Refresh Token)으로 사용자 개입 없이 새 토큰을 받아 온다.
PKCE와 그 밖의 그랜트
모바일 앱이나 SPA(Single Page Application)는 코드가 사용자 기기에 배포되므로 시크릿을 숨길 수 없다. 이를 보완하는 확장이 PKCE(Proof Key for Code Exchange)다. 클라이언트가 요청마다 임의의 검증 값(code_verifier)을 만들고 그 해시(code_challenge)를 인가 요청에 첨부한 뒤, 토큰 교환 때 원본 검증 값을 제출하면 인가 서버가 해시 일치를 확인한다. 인가 코드를 가로챈 공격자는 원본 검증 값을 모르므로 토큰을 얻지 못한다. 현재 보안 모범 사례는 클라이언트 유형과 무관하게 인가 코드 그랜트에 PKCE를 결합하는 것이다. 과거 사양에 있던 임플리시트 그랜트(Implicit Grant)는 토큰이 URL 프래그먼트로 직접 노출되는 문제로, 자원 소유자 비밀번호 그랜트는 앱이 비밀번호를 받는 구조 자체가 위임 원칙에 어긋나 모두 사용 중단이 권고된다. 사용자 없이 서버가 자기 자격으로 API를 쓰는 경우에는 클라이언트 자격 증명 그랜트(Client Credentials Grant)를 쓴다.
| 그랜트 | 대상 | 현재 권고 |
|---|---|---|
| 인가 코드 + PKCE | 웹, 모바일, SPA 전부 | 표준 권장 |
| 클라이언트 자격 증명 | 서버 간 통신 | 사용 |
| 임플리시트 | 과거의 SPA | 사용 중단 권고 |
| 비밀번호(ROPC) | 과거의 자사 앱 | 사용 중단 권고 |
OAuth와 OIDC, 그리고 보안 유의점
OAuth 2.0의 액세스 토큰은 자원 접근 허가일 뿐, 사용자가 누구인지 보증하는 신원 증명이 아니다. 소셜 로그인처럼 인증(Authentication)이 목적이라면 OAuth 위에 신원 계층을 얹은 OIDC(OpenID Connect)를 써야 한다. OIDC는 토큰 응답에 사용자 신원 클레임을 담아 서명한 ID 토큰(ID Token)을 추가하며, 이 토큰은 보통 JWT(JSON Web Token) 형식이다. 구현 시 보안 유의점으로는 리다이렉트 URI를 정확히 등록하고 완전 일치로 검증할 것, CSRF(Cross Site Request Forgery)를 막는 state 값을 반드시 확인할 것, 스코프를 필요 최소로 요청할 것, 토큰을 안전한 저장소에 두고 HTTPS만 사용할 것이 꼽힌다. 이 검증들 중 하나라도 빠지면 인가 코드 탈취나 토큰 바꿔치기 같은 실제 공격으로 이어진다.
면접에서 이렇게 물어본다
- OAuth 2.0의 네 가지 역할을 실제 소셜 연동 사례에 대입해 설명해 보라.
- 인가 코드 그랜트에서 액세스 토큰을 바로 주지 않고 코드를 거치는 이유는 무엇인가.
- PKCE가 어떤 공격을 어떻게 막는지 설명해 보라.
- OAuth 2.0과 OIDC의 차이, 액세스 토큰과 ID 토큰의 차이를 말해 보라.
- state 값과 리다이렉트 URI 검증이 없으면 어떤 공격이 가능한가.
웹에서 같이 읽기
- 웹 인증 방식 총정리 (Authentication)웹 서비스의 인증은 요청을 보낸 사용자가 누구인지 확인하는 절차다. HTTP는 무상태 프로토콜이므로 로그인 이후 요청마다 사용자를 식별할 수단이 필요하며, 세션, 토큰, API 키, OAuth를 비교해 각 방식의 적합한 상황을 정리한다.
- 쿠키와 세션 (Cookie, Session)쿠키는 서버가 브라우저에 저장하도록 지시하는 작은 키와 값의 쌍이고, 세션은 쿠키를 운반 수단으로 삼아 사용자별 상태를 서버 저장소에 보관하는 기법이다. 두 개념의 동작 원리와 보안 속성, 위협 대응을 다룬다.
- CSR과 SSR (Client Side Rendering, Server Side Rendering)CSR은 브라우저가 자바스크립트로 화면을 그리는 방식, SSR은 서버가 완성된 HTML을 내려보내는 방식이다. 초기 로딩, SEO, 서버 부하 관점의 차이와 SSG, ISR을 포함한 혼합 전략까지 정리한다.
- CSRF와 XSS (Cross Site Request Forgery, Cross Site Scripting)XSS는 공격자의 스크립트를 피해자 브라우저에서 실행시키는 공격이고, CSRF는 로그인된 브라우저를 속여 피해자 명의의 요청을 보내는 공격이다. 두 공격이 악용하는 신뢰 관계의 차이와 방어 수단을 정리한다.
이 개념, 내 코드에서는 어떻게 물어볼까요
데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.
공고 넣고 시작하기