홈 › 인증·로그인 › 02 / 3

2단계: Access/Refresh 토큰과 OAuth2 인가 코드

섹션 7진행 0 / 3

7. 정리

  • Access 는 짧고 무상태, Refresh 는 길고 서버가 기억한다. 리소스 서버는 Access 의 서명·exp·aud·jti 만 본다. Refresh 는 난수이며 인가 서버 저장소의 키일 뿐이다.
  • 회전 + family 로 재사용을 감지한다. 한 번 쓴 Refresh 는 "사용됨" 으로 남기고, 재사용이 오면 family 전체를 폐기한다. 정상 사용자도 끊기지만 그것이 탈취 신호다.
  • 로그아웃은 Refresh 삭제 + Access jti 거부 목록. 목록은 Access TTL 만큼만 산다. TTL 이 짧을수록 목록도 작고 무효화 빈틈도 짧다.
  • Refresh 는 HttpOnly + SameSite=Strict + Path 좁힌 쿠키, Access 는 메모리. localStorage 는 XSS 한 방에 털린다. 웹앱은 토큰을 브라우저에 주지 않는 BFF 가 기본.
  • aud 를 검사한다. 같은 인가 서버가 발급한 다른 API 용 토큰을 거부한다. 빠뜨리기 쉬운 1순위.
  • 인가 코드 흐름은 앞 채널에 60초 1회용 코드만 흘리고, 토큰은 뒷 채널(서버↔서버)로 받는다. 브라우저는 토큰을 보지 못한다.
  • PKCE 는 코드 가로채기를, state 는 로그인 CSRF 를 막는다. 방향이 반대이므로 둘 다 필요하다. redirect_uri 는 완전 일치, 틀리면 리다이렉트 없이 400.
  • 소셜 로그인은 남이 운영하는 인가 서버에 클라이언트로 붙는 것. 받은 토큰으로 프로필을 얻어 provider+sub 로 자사 계정과 연결하고, 자사 토큰을 새로 발급한다.
  • Spring 에서는 oauth2Login()(클라이언트), oauth2ResourceServer()(리소스), Spring Authorization Server(인가) 가 각 역할이고, application.yml 의 registration/provider 가 이 레슨의 registerClient 와 인가 서버 주소다.

다음 3단계 에서는 비밀번호와 토큰 위에 두 번째 요소를 얹습니다. Google Authenticator 가 쓰는 TOTP(RFC 6238) 를 HMAC-SHA1 로 직접 계산해 QR 등록·검증·백업 코드까지 만들고, 1~3단계를 하나의 로그인 흐름(비밀번호 → 2FA → Access/Refresh 발급)으로 통합합니다.

Spring Security 필터 체인에서 이 다단계가 어디에 끼어드는지, 회사 SAML SSO 가 이 흐름과 어떻게 공존하는지도 다룹니다.