오늘은 Security를 배우면서 접하게 된 JWT 토큰의 개념에 대해 정리해보겠습니다!
JWT Token?
JWT(JSON Web Token)은 웹 애플리케이션 간에 정보를 안전하게 전송하기 위해 사용되는 인증 및 권한 부여 메커니즘이며, 간결하고 자체적으로 안전한 방식으로 정보를 전달할 수 있어 많은 웹 애플리케이션에서 사용되고 있습니다.
JWT는 세 부분으로 구성됩니다.
- 헤더(Header)
- 페이로드(Payload)
- 서명(Signature)
1. 헤더(Header) :
토큰의 유형과 해싱 알고리즘 등의 메타데이터를 포함합니다. 일반적으로 'alg'(알고리즘)과 'typ'(토큰 유형) 필드가 포함됩니다.
예를 들면 다음과 같이 인코딩 될 수 있습니다. => '{"alg" : "HS256" , "typ" : "JWT"}'
2. 페이로드(Payload) :
실제로 전송하고자 하는 클레임(정보)들이 포함됩니다.
토큰에 포함될 클레임은 예를 들어 사용자 ID, 권한, 만료일 등이 있을 수 있습니다. 페이로드는 클레임의 정보를 담은 JSON 형식으로 인코딩 됩니다.
3. 서명(Signature) :
토큰이 신뢰할 수 있는 것임을 검증하기 위한 서명입니다.
서명은 헤더와 페이로드, 그리고 비밀 키를 사용하여 생성됩니다. 서명을 통해 토큰의 무결성과 인증이 보장됩니다.
JWT 작동 방식 간단 정리
- 사용자가 로그인하면 서버는 JWT를 생성하여 사용자에게 제공합니다.
- 클라이언트는 이후 요청에서 JWT를 헤더에 포함하여 서버에 전송합니다.
- 서버는 JWT의 성명을 확인하고 헤더와 페이로드를 해석하여 클레임의 정보를 사용합니다. 클라이언트의 요청을 인증하고 필요한 권한을 확인할 수 있습니다.
JWT 장점 / 주의 사항
[ 장점은 다음과 같습니다. ]
- 서버에 상태를 저장하지 않고도 클라이언트의 인증과 권한 부여를 처리할 수 있습니다.
- JWT는 티지털 서명을 통해 변조를 방지하고 토큰의 무결성을 보장합니다.
- 간결하고 자체적으로 안전한 방식으로 정보를 전달할 수 있습니다.
[ 주의 사항은 다음과 같습니다. ]
- JWT는 토큰에 포함된 정보를 안전하게 보호하지만, 토큰 자체는 안전한 저장소에서 관리되어야 합니다.
- 토큰의 만료 시간을 설정하여 보안을 강화할 수 있습니다.
간단 예제 코드
지금까지 JWT의 개념에 대해서 알아봤습니다.
간단한 예제를 통해 더 자세히 알아봅시다.
JWT 토큰의 예제에 사용된 라이브러리는 jjwt이며, 의존성 추가를 먼저 진행합니다.
<dependencies>
<!-- 다른 의존성들 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>
의존성 추가를 했다면, 다음으로는 JWT를 생성하고 검증하는 코드입니다.
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtExample {
private static final String SECRET_KEY = "your-secret-key"; // 비밀 키
public static void main(String[] args) {
// JWT 생성 예제
String jwt = createJwt("user123");
System.out.println("Generated JWT: " + jwt);
// JWT 검증 예제
boolean isValid = validateJwt(jwt);
System.out.println("Is JWT valid? " + isValid);
}
public static String createJwt(String subject) {
Date now = new Date();
Date expiration = new Date(now.getTime() + 3600000); // 1시간 후 만료
String jwt = Jwts.builder()
.setSubject(subject)
.setIssuedAt(now)
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
return jwt;
}
public static boolean validateJwt(String jwt) {
try {
Jws<Claims> claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(jwt);
return true; // 서명이 유효한 경우 true 반환
} catch (Exception e) {
return false; // 서명이 유효하지 않은 경우 false 반환
}
}
}
위 코드의 'createJwt' 메서드는 주어진 주제(Subject)를 가진 JWT를 생성합니다.
'validateJwt' 메서드는 주어진 JWT의 서명을 검증하여 유효한 지 확인합니다.
여기서 주의할 점은 위 코드는 단순히 JWT를 생성하고 검증하는 기본적인 예제 코드일 뿐입니다. 실제로는 클레임에 더 많은 정보를 추가하고, 비밀 키를 안전하게 관리해야 합니다. 또한, JWT를 전송할 때는 HTTPS와 같은 보안 프로토콜을 사용하는 것이 좋습니다.
출력 결과는 다음과 같습니다.
Generated JWT: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwiaWF0IjoxNjI0MzYzODI4LCJleHAiOjE2MjQzNjczMjgsImlzcyI6InRlc3QtaW50ZXJuYWwiLCJpYXQiOjE2MjQzNjM4Mjh9.KB3Hld4TMw6a2HwPL8oJtw-c4Gr8-R0EjQcINxhABKA
Is JWT valid? true
"Generated JWT" 라인에서는 생성된 JWT를 출력합니다. 그리고 "Is JWT valid?" 라인에서는 검증 결과를 출력합니다.
위 예제는 생성된 JWT가 유효하므로 'true'가 출력됩니다.
마치며
오늘은 JWT 토큰의 개념에 대해서 알아봤습니다.
다음 포스팅에서 뵙겠습니다.
'[ Concept ]' 카테고리의 다른 글
[ Concept ] Bluetooth UUID (0) | 2023.07.12 |
---|---|
[ Concept ] ResponseEntity 개념 및 장단점 (0) | 2023.07.11 |
[ Concept ] Git - 자주 사용하는 Git 명령어 모음 (0) | 2023.07.05 |
[ Concept ] JSONParser 개념 및 사용법 (0) | 2023.07.01 |
[ Concept ] DTO와 VO의 차이점 (0) | 2023.06.22 |