요즘 백엔드를 다시 만지작 거리고 있다.
작년까지만 해도 그냥 복붙하고 실행되면 일단 되는구나 했는데,
개념을 익히다 보니 조금씩 이해되는 부분이 있는 것 같다.
그리고 다시 돌아보니 내가 이전에 만든 서버는 보안이 엉망진창이었다.
그러나 이제는 그러면 안되는 단계에 왔으니 모르는 부분은 gpt에 물어가며 정리하고 있다.
이론 공부가 되고 나서 코드를 작성하게 되니 질문도 어떻게 해야 할 지 좀 알 것 같다.
JwtUtil 클래스 함수 설명 & 보안 개념 정리getSigningKey()
private Key getSigningKey() {
return Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
}
.env에서 불러온 비밀 키 문자열 (secret)javax.crypto.SecretKey (HMAC용)generateToken(String email)public String generateToken(String email) {
return Jwts.builder()
.setSubject(email)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + expirationTime))
.signWith(getSigningKey(), SignatureAlgorithm.HS256)
.compact();
}
sub: 사용자 이메일iat: 토큰 발급 시간exp: 만료 시간HMAC-SHA256 + getSigningKey()extractClaims(String token)
public Claims extractClaims(String token) {
return Jwts.parserBuilder()
.setSigningKey(getSigningKey())
.build()
.parseClaimsJws(token)
.getBody();
}
isTokenValid(String token, String email)public boolean isTokenValid(String token, String email) {
final String tokenEmail = extractClaims(token).getSubject();
return (tokenEmail.equals(email) && !isTokenExpired(token));
}
isTokenExpired(String token)private boolean isTokenExpired(String token) {
return extractClaims(token).getExpiration().before(new Date());
}
exp)이 현재 시간보다 이전인지 확인true: 만료됨false: 유효함| 용어 | 설명 |
|---|---|
| JWT (JSON Web Token) | 사용자의 인증 정보를 담은 JSON 기반의 토큰 |
| Claims | JWT 내부의 사용자 정보 (email, iat, exp 등) |
| 전자서명 | JWT 위조 방지를 위한 암호화 서명. 발급자가 진짜인지 확인 가능 |
| HMAC-SHA256 | SHA256 해시 + 비밀키 기반의 전자서명 방식 |
| 대칭키 | 서명 생성과 검증에 같은 키를 사용 (secret 키) |
HMAC-SHA256은 전자서명인가?전자서명의 한 방식
단, 일반적인 전자서명은 공개키/개인키를 사용하는 비대칭키 방식이고,
HMAC은 대칭키 기반의 서명 방식
🔑 HMAC-SHA256:
secret key + SHA-256 해시 알고리즘👉 이걸 이용해 메시지를 서명함으로써, 변조 여부를 검증할 수 있음.
✔️ 서버
JWT 내부의 payload 영역을 Claims 라고 부름.
이 안에 유저 정보, 권한, 만료일 등 다양한 값이 들어갈 수 있음.
예시:
{ "sub": "user@example.com", "iat": 1715678880, "exp": 1715765280 }
정리하면 JWT는 세 부분으로 구성됨:
HEADER.PAYLOAD.SIGNATURE
🔐 이 서명을 통해 토큰의 무결성(변조되지 않았는지) 를 확인
return claims.getExpiration().before(new Date());
✔️그냥 비교
exp)과 현재 시간을 비교해서,현재가 더 늦으면 → 만료됨 (true)확실히 AI가 코드를 작년보다 훨씬 잘 짜주긴 하는데, 내가 기본적인 것을 알고 있어야 하는 것은 여전한 것 같다.
그리고 이론을 공부하면서 하는 것과 아닌 것에 질문 차이도 스스로 느끼고 있다.
까먹지 말고 정리해야지...