JWT service에서 정보를 추출하는 방법에 대해서 보여드리겠습니다.
JWT 토큰을 조작하여 토큰에서 토큰을 검증하는 정보를 추출하는 등의
작업을 수행하려면 애플리케이션에 새로운 종속성을 포함해야 합니다.
모든 서비스를 구현하고 코드에 너무 깊이 빠져들기 전에
먼저 JWT 토큰이 무엇인지 이해해 보겠습니다.
JWT 토큰은 당사자 간에 전송할 claim을 나타내는 간결한 URL 저장 수단인 Json 웹 토큰의 약자입니다.
JWT는 세 부분으로 구성되어 있습니다.
header, payload와 signature가 있습니다.
header에는 JWT와 같은 토큰의 유형입니다.
JWT는 hmac이나 sh-250, sh-256 또는
RSA와 같은 로그인 알고리즘이 사용되고 있습니다.
토큰의 두 번째 부분은 claim를 포함하는
payload 입니다.
claim은 사용자와 추가 데이터에 대한
entity에 대한 진술입니다.
authorities나 claims와 같은
추가 정보도 여기에서 확인할 수 있습니다.
따라서 등록된 public과 private claims의
세 가지 유형이 있습니다.
registered claim은 필수는 아니지만
유용하고 반복 가능한 claim를 제공하기 위해
권장되는 사전 정의된 claim 입니다.
또한 만료 시간과 같은 것을 추가하는 subject가 있습니다.
이와 같은 subject를 통해 토큰 생성을 구현할 시기를 확인할 수 있습니다.
토큰의 마지막 부분은 signiture 입니다.
JWT의 중심이 누구인지 확인하고
메시지가 도중에 변경되지 않았는지
확인하는 데 사용됩니다.
code로 돌아가서 어떻게 claim을 만들 수 있는지,
extract할 수 있는지 알아보겠습니다.
JWT.IO
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
jwt.io
jwt.io 웹 사이트에서 payload를 가지고 플레이할 수 있습니다. 여기에 정보를 추가할 수 있습니다.
사용자 이름 추출 방법을 구현하기 전에
모든 claim을 추출하기 위한 코드를 구현하고 싶습니다.
또한 하나의 claim을 추출할 수 있는 다른 방법도 구현하고 싶습니다.
private Claims extractAllClaims(String token) throws AppException {
try {
return Jwts.parserBuilder()
.setSigningKey(getSignInKey())
.build()
.parseClaimsJws(token)
.getBody();
} catch (ExpiredJwtException e) {
throw new AppException(TOKEN_EXPIRED);
} catch (JwtValidationException e) {
throw new AppException(NOT_VALID_TOKEN);
}
}
- setSigningKey(getSignInKey()): 토큰을 생성하거나 디코딩할 때 SigningKey를 사용해야 한다.'
- getBody(): 모든 claim을 여기서 확인할 수 있습니다.
먼저 assigning key가 뭔지 알아보겠습니다.
Json Web token context signing key는
JWT에 디지털 서명하는 데 사용되는 비밀입니다.
signing key는 JWT signiture 부분을 생성하는 데 사용되며,
이는 JWT의 발신자가 자신이 주장하는 사람인지 확인하고
메시지가 도중에 변경되지 않았는지 확인하는데 사용됩니다.
그래서 우리는 이 JWT 키를 보내는 동일한 사람이나
동일한 고객이 누구인지 확인하고자 합니다.
signing key는 JWT 헤더에 지정된 로그인 알고리즘과 함께
signiture를 생성하는 데 사용됩니다.
특정 signiture 알고리즘과 키 크기는
애플리케이션의 보안 요구 사항과
signiture 당사자에 대한 신뢰 수준에 따라 달라집니다.
이를 위해 먼저 새 토큰, 새 signiture 또는 secret key를 생성해야 합니다.
보안상의 이유로 256 크기의 최소 할당 키가 필요합니다.
Secret-key 정의
@Service
public class JwtService {
@Value("${security.jwt.secret-key}")
private String secretKey;
@Value("${security.jwt.refresh-secret-key}")
private String refreshSecretKey;
private SecretKey getSignInKey() {
return Keys.hmacShaKeyFor(Decoders.BASE64URL.decode(secretKey));
}
private Key getRefreshSignInKey() {
return Keys.hmacShaKeyFor(Decoders.BASE64.decode(refreshSecretKey));
}
그 다음 단일 클레임을 추출하는 방법에 대해서 알아보겠습니다.
public<T>를 사용하겠습니다.
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
String token을 매개변수로 받습니다.
이 매개변수는 Claims객체를 입력으로 받아서 제네릭 타입 T를 반환하는 함수 입니다.
public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
}
private Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
}
Username과 만료일은 쉽게 얻을 수 있습니다.
'코드잇 스프린트 : 프론트엔드 단기심화 5기 (백엔드 협업)' 카테고리의 다른 글
[Youtube] Spring boot 3.0 - Secure your API with JWT Token 해석 및 프로젝트 적용 기록(3) (0) | 2025.01.30 |
---|---|
[Youtube] Spring boot 3.0 - Secure your API with JWT Token 해석 및 프로젝트 적용 기록(2) (0) | 2025.01.28 |
[Youtube] Spring boot 3.0 - Secure your API with JWT Token 해석 및 프로젝트 적용 기록(1) (0) | 2025.01.15 |
DTO를 어떻게 관리해야 할까? (1) | 2024.12.18 |
스프링 부트의 기본 기능 사용하기 (0) | 2024.11.23 |