본문 바로가기
IT

[JWT] 프로젝트 JWT 토큰 적용(Access, Refresh, OAuth 2.0)

by 유나니나노 2024. 11. 20.
반응형

 

JWT(Json Web Token)

개념

  • JSON 형식의 데이터를 안전하게 전송하기 위해 사용되는 토큰 기반 인증 메커니즘
  • 웹 애플리케이션의 사용자 인증 및 정보 교환에 사용
  • 서명을 포함하여 데이터의 무결성을 보장, 필요한 경우 암호화 가능

구조

  • Header (헤더)
  • Payload (페이로드)
  • Signature (서명)

Header

  • 토큰 타입 (JWT로 표시)
  • 해싱 알고리즘 (ex: HMAC SHA256 또는 RSA)
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

  • 토큰에 포함할 데이터를 나타냄 (클레임)
  • 클레임 종류
    • Registered Claims: JWT 표준에 정의된 클레임(iss - 발행자, exp - 만료 시간, sub - 주제, aud - 청중)
    • Public Claims: 사용자 정의 클레임, 충돌을 방지하기 위해 IANA에 등록하거나 네임스페이스를 사용할 수 있음
    • Private Claims: 발행자와 소비자 간에 정의된 클레임, 토큰 사용자가 임의로 설정할 수 있음
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

 

Signature

  • 헤더와 페이로드를 조합한 후 지정된 알고리즘(ex: HMAC SHA256)으로 해싱하여 생성
  • 비밀키나 공개/개인 키 쌍을 사용해 서명을 생성, 이를 통해 데이터의 무결성 보장
  • 생성 과정
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

 

프로젝트 적용

1. SpringConfig 클래스

  • Jwt가 먼저 실행되도록 기존 필터 체인에 추가
  • new JwtAuthenticationFilter(jwtTokenProvider)
    • JWT 토큰을 검증하여 사용자 인증을 처리하는 필터
    • 클라이언트의 요청 헤더에 포함된 JWT를 검증하고, 인증이 성공하면 보안 컨텍스트(SecurityContext)에 인증 정보를 설정
  • JwtTokenProvider는 JWT를 생성하고, 유효성을 검증하는 기능을 제공
  • UsernamePasswordAuthenticationFilter.class
    • Spring Security의 기본 인증 필터로 사용자 이름과 비밀번호 기반의 인증을 처리

 

2. JwtTokenProvider 클래스

  • CustomUserDetailsService
    • 사용자 세부 정보를 load하는 메서드, JWT 토큰을 검증할 때 사용
    • Base64로 인코딩된 jwt secretKey를 디코딩하여 byte 배열로 변환
    • keyByte를 사용해 HMAC-SHA 알고리즘용 비밀 키 객체를 생성
    • 생성된 비밀키는 JWT 토큰의 생성 및 검증에 사용

 

  • OAuth2AuthenticationToken 객체에서 사용자의 권한 정보를 가져옴
  • Access, Refresh Token 생성
    • setSubject: 토큰의 주제를 사용자 이름으로 설정
    • auth: 권한 정보를 클레임에 추가
    • loginId: 아이디를 클레임에 추가
    • setExpiration: 유효 기간 설정
    • signWith: HMAC-SHA256 알고리즘을 사용하여 비밀키로 서명

 

  • JWT 토큰을 복호화하여 토큰에 포함된 사용자 정보를 추출하고 그 정보를 기반으로 Spring Security에서 사용할 수 있는 인증 객체를 생성하는 역할
  • parseClaims(accessToken)
    • JWT 토큰을 복호화하여 claims에 저장(사용자 식별자, 권한 등)
  • UserDetails객체를 반환하는 loadUserByUsername(loginId) 호출을 통해 사용자 세부 정보 조회
  • claims.get("auth").toString().split(",")
    • 클레임 내부의 auth에서 콤마로 구분된 권한 목록을 가져옴
  • return new UsernamePasswordAuthenticationToken(userDetails, "", authorities);
    • Spring Security에서 인증된 사용자 정보와 권한을 나타내는 토큰

3. JwtAuthenticationFilter 클래스

  • 커스텀 필터의 doFilter 메서드, 클라이언트 요청이 들어올 때 JWT 토큰을 검증하고 인증을 설정하는 역할
  • Spring Security 필터 체인의 일부로 작동하며, 요청이 서버에 도달하기 전에 JWT 검증을 수행
  • isPermitAllEndpoint(requestURI)
    • permitAll()로 설정된 엔드포인트인지 확인하는 메서드
    • 인증이 필요 없는 엔드포인트에 대해서는 JWT 검증을 생략하고, 다음 필터로 요청 전달
  • resolveAccessAndRefreshToken(httpRequest, "accessToken")
    • HTTP 요청에서 accessToken 추출
  • accessToken이 null이 아니고 유효한 토큰이면 사용자 인증을 설정(setAuthentication)
  • accessToken이 유효하지 않으면 refreshToken 검증을 통해 accessToken 재발급 진행
반응형