security · high priority
Auth Strategies
JWT, OAuth 2.0 + PKCE, Session, NextAuth v5
학습 개요
탄생 배경
쉬운 설명
복잡한 개념을 실생활 비유로 설명합니다.
“콘서트 입장권 시스템: 티켓 구매(OAuth 인증) → 입장 팔찌(Access Token) → 팔찌로 자유롭게 이동(API 요청) → 팔찌 만료 시 갱신 카운터에서 재발급(Refresh Token)”
인증은 "당신이 누구인지 증명"하고, 인가는 "무엇을 할 수 있는지 결정"한다. JWT는 팔찌처럼 정보를 직접 담고 있어 매번 확인하지 않아도 된다.
핵심 개념
JWT는 Header.Payload.Signature 세 부분으로 구성된다. 서버가 서명했으므로 변조를 검증할 수 있고, Payload를 디코딩하면 사용자 정보를 바로 얻을 수 있다.
Header
알고리즘(HS256, RS256)과 토큰 타입(JWT) 명시
{ "alg": "RS256", "typ": "JWT" }Payload
Claims — 사용자 ID, 권한, 만료시간(exp) 등
{ "sub": "1234", "role": "admin", "exp": 1720000000 }Signature
Header + Payload를 비밀키로 서명한 값 — 변조 검증용
HMACSHA256(base64url(header) + "." + base64url(payload), secret)Access Token vs Refresh Token
- 수명: 15분~1시간
- API 요청 시 Authorization 헤더에 포함
- 탈취 시 짧은 시간만 유효
- Memory 또는 httpOnly cookie에 저장
- 수명: 7일~30일
- Access Token 갱신에만 사용
- httpOnly, Secure, SameSite=Strict cookie에 저장
- DB에서 무효화(revocation) 가능
JWT를 localStorage에 저장하면 안 되는 이유
localStorage는 JavaScript로 접근 가능해 XSS 공격에 취약하다. Access Token은 메모리(변수)에, Refresh Token은 httpOnly cookie에 저장하는 것이 권장된다.
실무 적용
어떤 상황에서 사용하는가
Next.js 앱에서 구글/카카오 소셜 로그인과 이메일 로그인을 동시에 지원할 때
어떻게 적용하는가
1) NextAuth v5 + Google/Kakao Provider 설정, 2) Credentials Provider로 이메일 로그인 추가, 3) middleware.ts로 보호된 경로 설정, 4) Access Token은 Memory, Refresh Token은 httpOnly cookie에 저장
흔한 실수와 안티패턴
- NEXTAUTH_SECRET 환경변수 미설정 (프로덕션 크래시)
- Refresh Token rotation 미구현 (탈취된 토큰으로 무한 갱신 가능)
- OAuth redirect URI와 실제 콜백 URL 불일치
- JWT 페이로드에 민감 정보(비밀번호, 카드번호) 포함
- Access Token 만료 후 자동 갱신 로직 미구현
면접 질문
답변 방향 힌트
XSS 취약점과 httpOnly cookie
반드시 언급할 키워드
- localStorage는 JS 접근 가능 → XSS 위험
- httpOnly cookie는 JS 접근 불가
- Access Token은 메모리에
- Refresh Token은 httpOnly cookie에
예상 꼬리 질문
- CSRF 공격이 무엇이고 어떻게 방어하나요?
- Refresh Token rotation이 무엇인가요?