OAuth vs JWT
OAuth 인가 코드 흐름(권한 위임 절차)을 5단계로 실행하고, 그 결과물인 토큰의 형식(JWT 3부분)을 해부·변조 시연으로 구분한다.
비밀번호 대신 '허락'을 건네는 절차
단계 목록 · 키보드 ←/→ 이동, Space 재생
OAuth 2.0은 '비밀번호 대신 허락을 건네는 절차'(프로토콜)이고 JWT는 '검증 가능한 주장을 담는 봉투'(토큰 형식)다 — 절차의 산출물이 그 봉투에 담기곤 할 뿐, 비교 대상이 아니다.
왜 헷갈리는가
"OAuth 쓸까 JWT 쓸까?"라는 질문 자체가 범주 오류다. 세션 vs JWT(상태 저장 위치), OAuth vs API 키(위임 방식), OIDC vs OAuth(신원 vs 권한)가 서로 다른 축인데 전부 '토큰'이라는 한 단어로 뭉개지며 혼란이 시작된다.
애니메이션이 보여주는 것
흐름 무대의 요점은 비밀번호가 구글 밖으로 나가지 않는다는 것이다. 인쇄 서비스가 받는 것은 일회용 코드였다가, 뒷채널에서 자기 비밀과 함께 액세스 토큰으로 바꾼다 — 코드를 도청당해도 client_secret 없이는 쓸모없다. 토큰의 scope는 '사진 읽기'로 제한된다.
해부 무대의 요점은 '읽을 수 있지만 고칠 수 없다'이다. payload는 base64일 뿐이라 누구나 읽는다(비밀 금지). 대신 서명이 header+payload에 묶여 있어, scope 한 글자만 고쳐도 검증이 무너진다. 서버는 DB 조회 없이 서명만으로 토큰을 믿을 수 있다 — 무상태 인증의 근거.
축을 나눠서 다시 보기
헷갈리는 짝들을 축별로 정리하면 이렇다.
- OAuth 2.0: 제3자에게 내 자원의 '권한'을 위임하는 절차. 산출물은 액세스 토큰(형식 무관 — JWT일 수도, 불투명 문자열일 수도).
- OIDC: OAuth 위에 '신원'(이 사람이 누구인가)을 얹은 확장 — ID 토큰(이건 JWT로 규격 고정)과 userinfo. '구글로 로그인'의 실체.
- JWT: 서명된 클레임 봉투. OAuth 없이도 쓴다(마이크로서비스 간 내부 인증, 이메일 검증 링크).
- 세션 vs JWT: 상태를 서버(세션 저장소)에 둘 것인가 토큰 안에 둘 것인가. JWT의 대가 — 만료 전 강제 폐기가 어렵다. 처방: 수명 짧은 액세스 토큰 + 리프레시 토큰 회전, 또는 중요한 작업만 서버 확인.
- PKCE: 모바일·SPA처럼 client_secret을 숨길 수 없는 클라이언트를 위한 코드 교환 증명 — 지금은 모든 공개 클라이언트의 필수.
실무에서 저지르는 실수
JWT payload에 개인정보·권한 원본을 넣는 것(누구나 읽는다), alg:none·약한 비밀키 허용(서명 검증 우회), 만료를 며칠로 잡고 폐기 수단이 없는 것, 액세스 토큰을 localStorage에 두고 XSS에 노출하는 것 — 넷 다 '봉투의 성질'을 절차의 보안으로 착각한 데서 나온다.
기억할 것
- OAuth = 위임 절차, JWT = 토큰 형식 — 층이 다르니 '무엇을 쓸까'의 대상이 아니다.
- 인가 코드 흐름의 핵심: 비밀번호는 안 건너가고, 코드는 뒷채널에서 비밀과 함께 토큰이 된다.
- JWT는 읽을 수 있어도 못 고친다 — 서명이 무상태 검증을 가능케 한다.
- JWT의 대가는 폐기 — 짧은 만료 + 리프레시 회전으로 다스린다.
- 로그인(신원)이 필요하면 OAuth가 아니라 OIDC를 찾아야 한다.