800===Dev Docs and License/Web Security

JWT 토큰 인증 - 안전한 웹 서비스를 위한 현대적 인증 방식 🔐

블로글러 2025. 3. 27. 18:17

안녕하세요! 오늘은 현대 웹 서비스에서 널리 사용되는 인증 방식인 JWT 토큰 인증에 대해 알아보겠습니다. 휴대폰 앱이나 웹사이트를 사용할 때 로그인을 하면 이후 페이지를 이동해도 계속 로그인 상태가 유지되는 것, 어떻게 가능한 걸까요? 🤔 바로 JWT와 같은 토큰 기반 인증 시스템이 그 비밀입니다!

등장 배경

초기 웹 서비스에서는 사용자 인증을 위해 세션 기반 인증을 주로 사용했습니다. 사용자가 로그인하면 서버에 세션을 생성하고, 클라이언트에는 세션 ID만 쿠키로 전달하는 방식이었죠. 하지만 이 방식은 몇 가지 문제점이 있었습니다:

[세션 기반 인증의 문제점]:

  1. 서버 부하 증가: 많은 사용자의 세션 정보를 서버에 저장해야 함
  2. 확장성 제한: 서버가 여러 대일 경우 세션 정보 공유의 어려움
  3. CORS(Cross-Origin Resource Sharing): 다른 도메인 간 인증 공유의 어려움

이러한 문제를 해결하기 위해 등장한 것이 바로 JWT(JSON Web Token) 입니다! JWT는 필요한 모든 정보를 토큰 자체에 포함시켜 서버에 상태를 저장할 필요가 없는 Stateless 인증 방식을 제공합니다. 😎

핵심 원리

JWT의 구조

JWT는 점(.)으로 구분된 세 부분으로 구성됩니다:

xxxxx.yyyyy.zzzzz
(헤더).(페이로드).(서명)
  1. 헤더(Header) 👒

    {
      "alg": "HS256",
      "typ": "JWT"
    }
    • alg: 서명 알고리즘 (예: HMAC SHA256, RSA)
    • typ: 토큰 타입 (JWT)
  2. 페이로드(Payload) 📦

    {
      "sub": "1234567890",
      "name": "홍길동",
      "role": "user",
      "iat": 1516239022,
      "exp": 1516242622
    }
    • 클레임(Claim): 사용자 ID, 이름, 권한 등의 정보
    • 등록된 클레임(Registered claims): iss(발행자), exp(만료시간), sub(주제), aud(대상) 등
    • 공개 클레임(Public claims): 충돌 방지를 위한 이름을 가진 정보
    • 비공개 클레임(Private claims): 당사자 간 정보 공유를 위한 사용자 정의 클레임
  3. 서명(Signature)

    HMACSHA256(
      base64UrlEncode(header) + "." + base64UrlEncode(payload),
      secret
    )
    • 헤더와 페이로드를 인코딩하고 비밀키로 서명
    • 토큰이 변조되지 않았음을 검증

JWT 인증 프로세스

  1. 사용자가 ID/PW로 로그인 요청 → 서버가 검증 후 JWT 토큰 발급 🔑
  2. 클라이언트는 받은 토큰을 저장(localStorage, sessionStorage, 쿠키 등)
  3. 이후 API 요청 시 Authorization 헤더에 토큰을 포함하여 전송
    Authorization: Bearer [JWT 토큰]
  4. 서버는 토큰의 서명을 검증하고 유효하면 요청 처리 ✓
  5. 토큰 만료 시 재로그인 또는 리프레시 토큰으로 갱신

사례 소개

JWT는 다양한 웹 서비스와 플랫폼에서 널리 사용되고 있습니다:

  1. REST API 인증: 구글, 페이스북과 같은 대형 서비스의 API 인증
  2. SPA(Single Page Application): React, Vue, Angular 등의 프레임워크 기반 앱
  3. 모바일 애플리케이션: 앱과 서버 간 인증
  4. 마이크로서비스: 서비스 간 인증 관리

Spring Security와 JWT 구현 예시

// JWT 토큰 생성 예시 (Java + Spring Security)
public String createToken(Authentication authentication) {
    UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();

    Date now = new Date();
    Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);

    return Jwts.builder()
            .setSubject(Long.toString(userPrincipal.getId()))
            .claim("name", userPrincipal.getName())
            .claim("role", userPrincipal.getAuthorities().stream()
                    .map(GrantedAuthority::getAuthority)
                    .collect(Collectors.toList()))
            .setIssuedAt(new Date())
            .setExpiration(expiryDate)
            .signWith(SignatureAlgorithm.HS512, jwtSecret)
            .compact();
}

// 토큰 검증 예시
public boolean validateToken(String token) {
    try {
        Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
        return true;
    } catch (SignatureException ex) {
        logger.error("유효하지 않은 JWT 서명");
    } catch (MalformedJwtException ex) {
        logger.error("유효하지 않은 JWT 토큰");
    } catch (ExpiredJwtException ex) {
        logger.error("만료된 JWT 토큰");
    } catch (UnsupportedJwtException ex) {
        logger.error("지원하지 않는 JWT 토큰");
    } catch (IllegalArgumentException ex) {
        logger.error("비어있는 JWT");
    }
    return false;
}

JWT 토큰 인증의 장단점 비교

구분 장점 단점
성능 서버에 상태 저장 없음 (부하 감소) 토큰 자체의 크기가 클 수 있음
확장성 다중 서버 환경에 적합 -
보안 서명으로 데이터 위변조 방지 한번 발급된 토큰 제어 어려움
호환성 다양한 플랫폼/언어에서 지원 -
구현 별도의 세션 스토리지 불필요 토큰 관리 로직 필요

주의사항 및 팁 💡

⚠️ 이것만은 주의하세요!

  1. JWT 토큰 보안

    • 토큰이 탈취되면 누구든 사용할 수 있음
    • 민감한 정보는 페이로드에 포함하지 말 것(암호화X)
    • 적절한 만료 시간 설정 필수
  2. JWT 토큰 저장 위치

    • localStorage: XSS 공격에 취약
    • 쿠키: httpOnly, secure 플래그 설정 권장
  3. Access Token + Refresh Token 전략

    • Access Token: 짧은 유효기간(수분~수시간)
    • Refresh Token: 긴 유효기간(수일~수주)

💡 꿀팁

  • 토큰 크기를 최소화하려면 페이로드에 필요한 정보만 포함
  • 중요 API는 토큰 검증 + 추가 권한 확인 로직 구현
  • RTR(Refresh Token Rotation) 패턴: 리프레시 토큰 사용 시마다 새로운 리프레시 토큰 발급
  • HTTPS 통신 필수: 토큰이 평문으로 전송되므로 암호화된 통신 채널 사용

마치며

지금까지 JWT 토큰 인증에 대해 알아보았습니다. 처음에는 어렵게 느껴질 수 있지만, 이 방식은 현대 웹 개발에서 필수적인 인증 방식입니다! 서버의 부하를 줄이고 확장성을 높이는 동시에, 적절한 보안 조치를 취한다면 안전하고 효율적인 인증 시스템을 구축할 수 있습니다. 여러분의 다음 프로젝트에 JWT를 도입해보는 건 어떨까요? 🚀

참고 자료 🔖

  • JWT 인증 방식의 이해와 적용 - F-Lab
  • JWT 토큰 인증 이란? (쿠키 vs 세션 vs 토큰) - Inpa Dev
  • [JWT] 토큰(Token) 기반 인증에 대한 소개 - VELOPERT.LOG
  • JWT를 이용한 로그인에서 보안을 높이는 방법 - velog

#JWT #인증 #토큰인증 #웹보안 #SpringSecurity

728x90