BackEnd/Spring Boot

[Java] Jwt๋ฅผ ์ด์šฉํ•˜์—ฌ Api์„œ๋ฒ„ ๊ฐœ์ธ์ •๋ณด ์•”ํ˜ธํ™”ํ•˜๊ธฐ

ddonghyeo 2023. 9. 1. 23:44

์„œ๋ฒ„์˜ HTTPS์„ค์ •์€ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ ์ „์†ก ๊ณผ์ •์— ๋ˆ„๊ตฐ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๋กœ์ฑ„ ๋ณผ ์ˆ˜ ์—†๋„๋ก ๋ณดํ˜ธํ•˜๋Š” ์ˆ˜๋‹จ์ด๋‹ค.

 

ํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ์„œ๋ฒ„์˜ ํ†ต์‹ ์ด ์•ˆ์ „ํ•œ ๊ฒƒ์ด์ง€, ์„œ๋ฒ„๊ฐ€ ์•ˆ์ „ํ•˜๋‹ค๋Š”๊ฒŒ ์•„๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ Client์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€๊ฐ™์€ ๊ฐœ์ธ์ •๋ณด๋ฅผ ์„œ๋ฒ„์—์„œ ์ „์†กํ–ˆ๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ๊ฐœ์ธ์ •๋ณด๋ฅผ DB์— ์ €์žฅํ•ด๋‘์—ˆ๋‹ค๋ฉด,

 

๊ทธ DB๊ฐ€ ๋…ธ์ถœ๋œ๋‹ค๋ฉด ๊ฐœ์ธ์ •๋ณด๊ฐ€ ๋…ธ์ถœ๋˜๋Š” ๊ฒƒ์ด๋‹ค... ๐Ÿ˜ฌ

 

๊ทธ๋ž˜์„œ JWT(JSON Web Token)์„ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™” ํ•  ๊ฒƒ์ด๋‹ค.

 

JWT๋Š” Base64 URL ์ธ์ฝ”๋”ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ† ํฐ์˜ ๋‚ด์š”์„ ์•”ํ˜ธํ™”ํ•˜๊ณ  ์„œ๋ช…ํ•˜์—ฌ ์ธ์ฆ ๋ฐ ๊ถŒํ•œ๋ถ€์—ฌ๋ฅผ ํ•ด์ค€๋‹ค.

 

JWT๋Š” ์„œ๋ช…์„ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ๊ฒ€์ฆ ๊ณผ์ •์„ ๊ฑฐ์ณ ๋ณ€์กฐ๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ์„ค์ •ํ•˜์—ฌ ํ† ํฐ์˜ ์•…์šฉ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

 

๋ณดํ†ต AccessToken๊ณผ RefreshToken์œผ๋กœ ๋‚˜๋‰˜๋Š”๋ฐ, ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์— ํฌ์ŠคํŒ… ํ•˜๊ฒ ๋‹ค.

 

ํ† ํฐ ์ƒ์„ฑ

public class JwtUtil {

    Long exp = 3600000L; // 1์‹œ๊ฐ„(3600000๋ฐ€๋ฆฌ์ดˆ)

    private static final String SECRET_KEY = "SecretKey"; // JWT๋ฅผ ์•”ํ˜ธํ™”ํ•˜๊ธฐ ์œ„ํ•œ Secret Key

    public static String generateToken(String subject, long ttlMillis) {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        // JWT ํ† ํฐ ์ƒ์„ฑ
        String token = Jwts.builder()
                .setSubject(subject) //subject ์„ค์ •
                .setIssuedAt(now) //ํ† ํฐ์ด ๋ฐœ๊ธ‰๋œ ์‹œ๊ฐ„
                .setExpiration(new Date(nowMillis + exp)) //์œ ํšจ๊ธฐ๊ฐ„ ์„ค์ •
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY) //์„œ๋ช…
                .compact(); //ํ•ฉ์น˜๊ธฐ
        return token;
    }

exp๋Š” ํ† ํฐ์˜ ๋งŒ๋ฃŒ์‹œ๊ฐ„์ด๋‹ค. accessToken, refreshToken ๋“ฑ ์šฉ๋„์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค.
๋งŒ๋ฃŒ์‹œ๊ฐ„์ด ๊ธธ์ˆ˜๋ก ํƒˆ์ทจ๋‹นํ•  ํ™•๋ฅ ์ด ๋†’์•„์ง„๋‹ค.
๋”ฐ๋ผ์„œ ์งง์€ ์ธ์ฆ์„ ์š”๊ตฌํ•  ๋•Œ์—๋Š” ์งง์€ ๋งŒ๋ฃŒ์‹œ๊ฐ„์„ ๋‘๋Š”๊ฒŒ ์ข‹๋‹ค.

 

ํ† ํฐ ์œ ํšจ์„ฑ ๊ฒ€์ฆ

public static boolean validateToken(String token) {
        try {
            // JWT ํ† ํฐ ํŒŒ์‹ฑ
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(KEY)
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

ํ† ํฐ์ด ์œ ํšจํ•œ์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๋กœ์ง์ด๋‹ค. ์„ค์ •ํ•ด๋‘” KEY๋ฅผ ํ†ตํ•ด ํ† ํฐ์„ ํŒŒ์‹ฑํ•˜๊ณ  ์œ ํšจํ•œ ํ† ํฐ์ด๋ฉด true, ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

ํ† ํฐ Body๊ฐ’ ์–ป๊ธฐ

public static Claims getJwtBody(String token) {
        // JWT ํ† ํฐ ํŒŒ์‹ฑ
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(KEY)
                .build()
                .parseClaimsJws(token)
                .getBody();
        return claims;
    }

ํ† ํฐ ๋‚ด์— Body๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด, SignKey๋ฅผ ํ†ตํ•ด ํŒŒ์‹ฑํ•˜๊ณ  getBody()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.