본문 바로가기

Spring boot

JWT 이란?

반응형

JWT이란 JSON Web Token의 약자로 주로 로그인 할 때 서버에서 생성해서 유저에게 발급해준다.

또한 웹에서 정보를 안전하게 전달하기 위한 열려있는 표준이다.

JWT는 JSON 형식으로 구성되어 있으며, 클레임(claim)이라는 속성을 사용하여 필요한 정보를 포함하고 서명(signature)을 통해 인증과 데이터 무결성을 보장하며, 주로 인증(Authentication)과 정보 교환을 위해 사용된다.

 

 

JWT는 기본적으로 세 부분으로 구성된다

  •  Header
  • Payload
  • Signature

생선된 토큰은....

  • 서버는 생성된 JWT 토큰을 클라이언트에 응답으로 반환합니다.
  • 이때 토큰을 응답 헤더에 담아서 반환하거나, 응답 바디(JSON)에 담아 반환할 수 있습니다.
  • 일반적으로 HTTP 응답 헤더에 Authorization이라는 필드로 JWT를 포함시킵니다.

헤더

 

  • kid : 서명 시 사용하는 키(Public/Private Key)를 식별하는 값
  • typ : 토큰 유형
  • alg : 서명 암호화 알고리즘 HS256(HMAC SHA-256), HS512, RS256(RSASSA SHA-256), ES256(ECDSA P-256 curve SHA-256)

 

페이로드

 

  • 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨 있습니다.
  • 클레임(Claim)은 Key/Value 형태로 된 값을 가집니다.
  • 저장되는 정보에 따라 등록된 클레임(Registered Claims), 공개 클레임(Public Claims), 비공개 클레임(Private Cliams)로 구분됩니다.
JWT Payload 예시 (출처: BizSpring)
  • iss : 토큰 발급자(issuer) – Public Claims
  • sub : 토큰 제목(subject) – Public Claims
  • iat : 토큰 발급 시간(issued at) – Public Claims
  • exp : 토큰 만료 시간(expiration) – Public Claims
  • roles : 권한 – Private Cliams

Signature (서명)

  • Header(헤더) 에서 정의한 알고리즘 방식(alg)을 활용합니다.
  • Header(헤더)+ 페이로드(Payload)와 서버가 갖고 있는 유일한 key 값을 합친 것을 헤더에서 정의한 알고리즘으로 암호화합니다.
JWT Signature 예시 (출처: BizSpring)
  • Header(헤더) 와 페이로드(Payload)는 단순히 인코딩된 값이기 때문에 제 3자가 복호화 및 조작할 수 있지만, Signature(서명)는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없습니다. 이는 토큰의 위변조 여부를 확인하는데 사용됩니다.

 

여기서 Secret Key값은 보안이 정말 중요하므로 환경변수에 박든지, CI/CD 가 구축되어 있다면 github actions의 secrets 기능을 써도 된다.

 

public boolean validateToken(String token){
    try{
        Claims claims = Jwts.parserBuilder()
                            .setSigningKey(secretKey())
                            .build()
                            .parseClaimsJws(token)
                            .getBody();//페이로드 부분 추출
        return true;
    } catch (ExpiredJwtException | SignatureException e){
        return false;
    } //토큰이 만료되었거나 변조되었다면

} //JWT 토큰 유효성 검증

이 코드는 클라이언트가 요청을 보낼 때 헤더에 담겨져 있는 토큰의 유효성을 검사하는 코드이다

 

  • Claims: JWT 페이로드에 포함된 클레임 데이터를 표현하는 객체.
  • Jwts: JWT 생성, 파싱, 검증 등을 위한 유틸리티 클래스.
  • parserBuilder(): JWT 파서를 빌드하기 위한 빌더를 생성하는 메서드.
  • setSigningKey(): JWT 서명 검증에 사용할 비밀키를 설정하는 메서드.
  • build(): 설정된 빌더를 바탕으로 JwtParser 객체를 생성하는 메서드.
  • parseClaimsJws(String token): 주어진 토큰을 파싱하고 검증하는 메서드.
  • getBody(): 검증된 JWT에서 페이로드 클레임을 추출하는 메서드.
  • ExpiredJwtException: 토큰이 만료되었을 때 발생하는 예외.
  • SignatureException: 서명이 잘못되었거나 변조된 경우 발생하는 예외.

참고로 secretKey()는 

private byte[] secretKey(){
    return Decoders.BASE64.decode(jwtConfig.getSecret());
}//원래는 secret key 값을 바로 바꿔 줄 수 있었으나 그 메소드는 deprecated 되어서
//디코딩을 해주어야 합니다

 

 

이러하다

반응형