백엔드 면접 용어 사전
인증·인가

OAuth 2.0

제3자 앱에 자원 접근 권한을 위임하는 인가 프레임워크. 인증 규격은 그 위의 OIDC가 담당한다.

사용자가 비밀번호를 주지 않고 제3자 앱에 자기 자원 접근 권한을 위임하는 프로토콜.

무엇을 해결하나

"이 앱이 내 구글 드라이브 파일을 읽게 하고 싶다"

❌ 구글 비밀번호를 앱에 알려 준다

  • 앱이 메일도 읽고 계정도 삭제할 수 있다. 비밀번호를 바꿔야만 회수된다

✅ OAuth

  • "드라이브 읽기 권한만" 위임. 언제든 회수 가능. 비밀번호는 안 넘어간다

네 역할

역할누구
Resource Owner사용자(나)
Client권한을 요청하는 앱
Authorization Server구글 로그인 서버
Resource Server구글 드라이브 API

Authorization Code Grant — 표준 흐름

다이어그램 로딩 중…

왜 코드를 한 번 거치나 — 핵심 설계

토큰을 바로 주지 않고 code를 먼저 주는 이유

  • redirect는 브라우저 주소창을 거친다
  • 토큰을 직접 주면 URL·브라우저 기록·리퍼러에 남는다

code는

  • 일회용이고 수명이 짧다(보통 10분)
  • 토큰으로 바꾸려면 client_secret이 필요하다 (서버만 아는 값)
  • 브라우저에서 code가 새어 나가도 토큰을 얻을 수 없다

PKCE — 이제는 모든 클라이언트에 권장

모바일 앱·SPA는 client_secret을 안전하게 보관할 수 없다(디컴파일하면 나온다). 그래서 매 요청마다 만드는 일회용 비밀을 쓴다.

  • ① 클라이언트가 무작위 code_verifier 생성

  • ② code_challenge = SHA256(code_verifier) 를 인증 요청에 첨부

  • ③ 토큰 교환 시 원본 code_verifier 를 제시

  • ④ 서버가 SHA256(verifier) == challenge 확인

  • 공격자가 code를 가로채도 verifier를 모르면 토큰을 못 받는다

OAuth 2.1에서는 모든 흐름에 PKCE가 필수가 된다.

사라진/피해야 할 방식

방식상태
Implicit폐기. 토큰이 URL에 노출됨 → Authorization Code + PKCE로 대체
Resource Owner Password폐기. 비밀번호를 앱에 넘기므로 OAuth의 취지에 반함
Client Credentials유효. 서버 간 통신(사용자 없음)
Device Code유효. TV·CLI처럼 입력이 불편한 기기

scope — 최소 권한

  • scope=drive.readonly — ← 읽기만
  • scope=drive — ← 전체 접근 ✗ 과도하다

필요한 최소 범위만 요청한다. 과한 권한을 요구하면 사용자가 동의를 거부하기도 한다.

가장 중요한 오해 — OAuth는 인증이 아니다

OAuth 2.0 = 인가(Authorization) 프로토콜 "이 앱이 내 자원에 접근해도 된다"는 위임이지, "이 사용자가 누구인지"를 알려 주는 규격이 아니다

Access Token만으로 로그인 처리를 하면 위험하다. 그 토큰이 우리 앱을 위해 발급된 것인지 확인할 방법이 없어, 다른 앱용 토큰을 가져와 남의 계정으로 로그인할 수 있다(confused deputy).

로그인이 목적이면 OIDC를 써야 한다. OIDC는 OAuth 위에 id_token(누구인지를 담은 서명된 JWT)을 추가한 규격이다.

이 구분을 짚으면 면접에서 확실히 좋은 인상을 준다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 인증·인가 — 세션·JWT·OAuth 2.1·CSRF