JWT(Json Web Token)λ JSON νμμΌλ‘ μ¬μ©μ μ 보λ₯Ό μμ νκ² μ λ¬νκΈ° μν ν ν° κΈ°λ° μΈμ¦ λ°©μμ λλ€. μ¬μ©μκ° λ‘κ·ΈμΈνλ©΄ μλ²λ JWTλ₯Ό λ°κΈνκ³ , μ΄ν μμ²λ§λ€ ν΄λΌμ΄μΈνΈλ μ΄ ν ν°μ ν€λμ λ΄μ 보λ λλ€. μλ²λ λ³λμ μΈμ μ μ₯μ μμ΄λ ν ν°λ§μΌλ‘ μ¬μ©μλ₯Ό μΈμ¦ν μ μμ΅λλ€.
JWTλ .μΌλ‘ ꡬλΆλ μΈ λΆλΆμΌλ‘ μ΄λ£¨μ΄μ§λλ€.
xxxxx.yyyyy.zzzzz
Header (ν€λ)
ν ν°μ νμ
(JWT)κ³Ό ν΄μ± μκ³ λ¦¬μ¦(μ: HS256) μ 보λ₯Ό λ΄μ΅λλ€.
{
"alg": "HS256",
"typ": "JWT"
}
Payload (νμ΄λ‘λ)
μ€μ λ΄κ³ μΆμ μ¬μ©μ μ 보(Claims)μ
λλ€.
μ: μ¬μ©μ μ΄λ¦, κΆν, λ§λ£ μκ° λ±.
{
"sub": "user123",
"iat": 1691234567,
"exp": 1691238167
}
Signature (μλͺ
)
Headerμ Payloadλ₯Ό λΉλ° ν€(Secret Key)λ‘ μλͺ
ν κ°μ
λλ€. ν ν° μΒ·λ³μ‘° μ¬λΆλ₯Ό κ²μ¦ν λ μ¬μ©λ©λλ€.
μ΄λ²μ μμ±ν JwtTokenProvider ν΄λμ€λ Spring Securityμμ JWTλ₯Ό μμ±νκ³ κ²μ¦νλ ν΅μ¬ μν μ λ΄λΉν©λλ€. ꡬ체μ μΌλ‘λ λ€μκ³Ό κ°μ μν μ μνν©λλ€.
generateToken)getUsername)validate)package com.example.demo.security;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.util.Date;
@Component
public class JwtTokenProvider {
// HMAC-SHA μκ³ λ¦¬μ¦μ μν μν¬λ¦Ώ ν€μ ν ν° λ§λ£ μκ°
private final SecretKey key;
private final long expirationMs;
// μμ±μ: application.ymlμμ μν¬λ¦Ώ ν€μ λ§λ£ μκ° μ£Όμ
public JwtTokenProvider(
@Value("${jwt.secret}") String secret,
@Value("${jwt.expiration-ms}") long expirationMs
) {
byte[] keyBytes = (secret.matches("^[A-Za-z0-9+/=]+$") ? Decoders.BASE64.decode(secret) : secret.getBytes());
this.key = Keys.hmacShaKeyFor(keyBytes);
this.expirationMs = expirationMs;
}
// ν΅μ¬: ν ν°μ λ§λ€κ³ κ²μ¦νλ λ° νμν μν¬λ¦Ώ ν€μ λ§λ£ μκ°μ application.ymlμμ κ°μ Έμμ μ€λΉνλ κ³Όμ
// β
JWT ν ν° μμ±
public String generateToken(UserDetails user) {
Date now = new Date();
Date exp = new Date(now.getTime() + expirationMs);
return Jwts.builder()
.setSubject(user.getUsername()) // ν ν°μ 주체(μ¬μ©μ μ΄λ¦)
.setIssuedAt(now) // ν ν° λ°ν μκ°
.setExpiration(exp) // ν ν° λ§λ£ μκ°
.signWith(key, Jwts.SIG.HS256) // μν¬λ¦Ώ ν€λ‘ HS256 μκ³ λ¦¬μ¦μ μ¬μ©νμ¬ ν ν°μ μλͺ
.compact(); // μ΅μ’
μ μΌλ‘ λ¬Έμμ΄λ‘ μμΆνμ¬ λ°ν
}
// ν΅μ¬: ν ν°μ μ¬μ©μ μ΄λ¦, λ°ν μκ°, λ§λ£ μκ° λ±μ μ 보λ₯Ό λ΄κ³ , μν¬λ¦Ώ ν€λ‘ μλͺ
νμ¬ μμ νκ² μμ±νκ³ λ¬Έμμ΄ ννλ‘ λ³ννλ κ³Όμ
// β
ν ν°μμ μ¬μ©μ μ΄λ¦ μΆμΆ
public String getUsername(String token) {
return Jwts.parser()
.verifyWith(key) // ν ν°μ μλͺ
μ μν¬λ¦Ώ ν€λ‘ κ²μ¦
.build()
.parseSignedClaims(token) // ν ν°μ νμ±νκ³ ν΄λ μ(μ 보)μ κ°μ Έμ΄
.getPayload()
.getSubject(); // ν ν°μ 주체(μ¬μ©μ μ΄λ¦) λ°ν
}
// ν΅μ¬: ν ν°μ΄ μ ν¨νμ§ λ¨Όμ νμΈν λ€μ, κ·Έ μμ λ΄κΈ΄ μ¬μ©μ μ΄λ¦μ μΆμΆνλ κ³Όμ
// β
ν ν° μ ν¨μ± κ²μ¦
public boolean validate(String token) {
try {
// ν ν°μ νμ±νκ³ μλͺ
μ κ²μ¦
Jwts.parser().verifyWith(key).build().parseSignedClaims(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
// ν ν°μ΄ μλͺ»λμκ±°λ λ§λ£λ κ²½μ° μμΈ λ°μ
return false;
}
}
// ν ν° λ§λ£ μκ° λ°ν
public long getExpirationMs() {
return expirationMs;
}
}
public JwtTokenProvider(@Value("${jwt.secret}") String secret, @Value("${jwt.expiration-ms}") long expirationMs)
application.ymlμμ jwt.secretκ³Ό jwt.expiration-ms κ°μ μ½μ΄μ΅λλ€. μ΄ κ°λ€λ‘ HMAC-SHA256 μκ³ λ¦¬μ¦μ λ§λ SecretKey κ°μ²΄λ₯Ό μμ±νμ¬ ν ν° μλͺ
μ μ¬μ©ν©λλ€.
generateToken)public String generateToken(UserDetails user)
user.getUsername()μ ν ν°μ Subjectλ‘ μ€μ νκ³ , λ°ν μκ°(IssuedAt)κ³Ό λ§λ£ μκ°(Expiration)μ μ§μ ν©λλ€. signWith(key, Jwts.SIG.HS256)λ₯Ό ν΅ν΄ μν¬λ¦Ώ ν€ κΈ°λ°μΌλ‘ μλͺ
νμ¬ μλ³μ‘°λ₯Ό λ°©μ§ν©λλ€. μ΅μ’
μ μΌλ‘ λ¬Έμμ΄ ννμ JWTλ₯Ό λ°νν©λλ€.
getUsername)public String getUsername(String token)
ν ν°μ νμ±νκ³ μλͺ μ κ²μ¦ν λ€, Payloadμ Subject(μ¬μ©μ μ΄λ¦)λ₯Ό κΊΌλ΄μ΅λλ€.
validate)public boolean validate(String token)
parseSignedClaims(token) μ€ν μ μμΈκ° λ°μνμ§ μμΌλ©΄ trueλ₯Ό λ°νν©λλ€. λ§λ£λμκ±°λ μμ‘°λ κ²½μ° JwtExceptionμ΄ λ°μνμ¬ falseλ₯Ό λ°νν©λλ€.
JwtTokenProviderλ ν ν° λ°κΈκ³Ό κ²μ¦ λ‘μ§μ λ΄λΉνλ©° Spring Securityμ μμ°μ€λ½κ² μ°λλ©λλ€.Authentication κ°μ²΄λ‘ λ³νν μ μμ΅λλ€.true/false λμ "λ§λ£λ¨ / μμ‘°λ¨ / νμ μ€λ₯" λ± κ΅¬μ²΄μ μΈ μλ΅μ μ 곡νμ¬ ν΄λΌμ΄μΈνΈκ° λ¬Έμ λ₯Ό μ νν νμ
ν μ μλλ‘ λμ΅λλ€.