study/๋ณด์•ˆ

JWT๋ž€? (JSON Web Token)

dddzr 2025. 2. 16. 22:08

๐Ÿ” JWT๋ž€? (JSON Web Token)

  • JWT(JSON Web Token)๋Š” ์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ์ •๋ณด ์ „๋‹ฌ์„ ์œ„ํ•œ ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ ๋ฐฉ์‹!
  • ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๊ณ (stateless) ์ธ์ฆํ•  ์ˆ˜ ์žˆ์–ด์„œ,
    REST API ๋“ฑ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค. 

โœ… 1. JWT ๊ตฌ์กฐ

JWT๋Š” .(์ )์œผ๋กœ ๊ตฌ๋ถ„๋œ 3๊ฐœ์˜ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

 

๐Ÿ“– ์˜ˆ์‹œ

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIiLCJyb2xlIjoiQURNSU4iLCJpYXQiOjE2OTQ2MjQ4MDB9.f9XY4qkAeUpmEYAf_CtwJfpFq93j98gVwVFXD2DdeuA

 

๐Ÿ”น 1. Header (ํ—ค๋”)

  • ํ† ํฐ์˜ ํƒ€์ž…(JWT)๊ณผ ์„œ๋ช…์— ์‚ฌ์šฉํ•  ์•Œ๊ณ ๋ฆฌ์ฆ˜(์˜ˆ: HS256, RS256)์„ ํฌํ•จ
{
  "alg": "HS256",
  "typ": "JWT"
}

 

๐Ÿ”น 2. Payload (ํŽ˜์ด๋กœ๋“œ)

  • ์‚ฌ์šฉ์ž ์ •๋ณด(ํด๋ ˆ์ž„, Claim)**๊ฐ€ ๋‹ด๊ธด ๋ถ€๋ถ„
  • ํ† ํฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๋ฉด ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ๋งŽ์ด ์žก์•„๋จน๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ๋‹ด๋„๋ก ํ•ด์•ผํ•œ๋‹ค!
{
  "sub": "user12",  // ์‚ฌ์šฉ์ž ID
  "role": "ADMIN",  // ์—ญํ• (Role)
  "iat": 1694624800 // ๋ฐœ๊ธ‰ ์‹œ๊ฐ„ (Unix Timestamp)
}

 

๐Ÿ”น 3. Signature (์„œ๋ช…)

  • JWT๊ฐ€ ๋ณ€์กฐ๋˜์ง€ ์•Š์•˜์Œ์„ ๋ณด์žฅํ•˜๋Š” ์—ญํ• 
  • HMAC, RSA, ECDSA ๋“ฑ์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•ด ์ƒ์„ฑ
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secretKey
)

โœ… 2. JWT ํŠน์ง•

โœ” ๋ฌด์ƒํƒœ(stateless)

  • ์„œ๋ฒ„์—์„œ ์„ธ์…˜์„ ์œ ์ง€ํ•  ํ•„์š” ์—†์Œ โ†’ ์„œ๋ฒ„ ๋ถ€ํ•˜ ๊ฐ์†Œ
    โœ” ์ž์ฒด ์ธ์ฆ(Self-contained)
  • ์‚ฌ์šฉ์ž ์ •๋ณด๊ฐ€ ํ† ํฐ์— ํฌํ•จ๋จ โ†’ DB ์กฐํšŒ ์—†์ด ์ธ์ฆ ๊ฐ€๋Šฅ
    โœ” ์•ˆ์ „ํ•œ ์„œ๋ช…(Signature) ๊ฒ€์ฆ
  • ๋น„๋ฐ€ ํ‚ค(HS256) ๋˜๋Š” ๊ณต๊ฐœ ํ‚ค(RS256)๋กœ ์„œ๋ช… โ†’ ๋ณ€์กฐ ๋ฐฉ์ง€

 

โญ MSA์—์„œ ์‚ฌ์šฉ ์ด์œ 

  • ๊ฐ ์„œ๋น„์Šค ์ž์ฒด ์ธ์ฆ: JWT๋Š” ํ† ํฐ ์ž์ฒด์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ธ์ฆ ์„œ๋ฒ„๊ฐ€ ์—†์ด๋„ ๊ฐ ์„œ๋น„์Šค๊ฐ€ JWT๋ฅผ ํ†ตํ•ด ์ธ์ฆ์„ ์‰ฝ๊ฒŒ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ™•์žฅ์„ฑ ๋ฐ ์œ ์—ฐ์„ฑ: ์„œ๋ฒ„ ํ™•์žฅ(์Šค์ผ€์ผ๋ง)์ด๋‚˜ ๋‹ค๋ฅธ ์„œ๋น„์Šค ์—ฐ๋™์‹œ์—๋„ ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์–ด์„œ ํ™•์žฅ์„ฑ๊ณผ ์œ ์—ฐ์„ฑ์ด ๋›ฐ์–ด๋‚จ.

โœ… 3. JWT ์ธ์ฆ ํ๋ฆ„

1๏ธโƒฃ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ์š”์ฒญ (ID/PW)
2๏ธโƒฃ ์„œ๋ฒ„๊ฐ€ JWT๋ฅผ ์ƒ์„ฑ ํ›„ ๋ฐ˜ํ™˜, JWT๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก์— ์ €์žฅ.
3๏ธโƒฃ ํด๋ผ์ด์–ธํŠธ๊ฐ€ JWT๋ฅผ ํฌํ•จํ•ด ์š”์ฒญ (Authorization: Bearer <token>)
4๏ธโƒฃ ์„œ๋ฒ„์—์„œ JWT ๊ฒ€์ฆ ํ›„ ์‘๋‹ต ๋ฐ˜ํ™˜

โญ ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ธ์ฆ๊ณผ ๋‹ฌ๋ฆฌ ์„œ๋ฒ„๊ฐ€ ๋ณ„๋„๋กœ ์ƒํƒœ(Session)๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š์•„๋„ ๋จ!


โœ… 4. JWT ์ƒ์„ฑ

ํ‚ค ์ƒ์„ฑ ๋ฐฉ์‹์— ๋”ฐ๋ผ ์ œ๊ณต, ๊ฒ€์ฆ ๋ฐฉ์‹์ด ๋‹ค๋ฅด๋‹ค!!

  • ๊ฐ•๋ ฅํ•œ ํ•ด์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜(HMAC-SHA256, RS256 ๋“ฑ) ์‚ฌ์šฉ
  • ์ทจ์•ฝํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜(์˜ˆ: none ์•Œ๊ณ ๋ฆฌ์ฆ˜) ์‚ฌ์šฉ โŒ

 

๐Ÿ‘‰ ํ‚ค ์ €์žฅ ์œ„์น˜

  • ํŒŒ์ผ ์‹œ์Šคํ…œ (private_key.pem, public_key.pem)
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (MySQL, PostgreSQL, Redis ๋“ฑ)
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋˜๋Š” ๋ณด์•ˆ ์„œ๋น„์Šค (AWS Secrets Manager, HashiCorp Vault)
  • HSM (Hardware Security Module) ๊ฐ™์€ ํ•˜๋“œ์›จ์–ด ๊ธฐ๋ฐ˜ ํ‚ค ๊ด€๋ฆฌ ์‹œ์Šคํ…œ

 

โœ… 4-0. ํ‚ค ์ƒ์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€

์ผ๋ฐ˜์ ์œผ๋กœ jsonwebtoken ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•œ JwtTokenProvider์„ ์ž‘์„ฑํ•˜์—ฌ ์‚ฌ์šฉ.

Private key๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

 

๐Ÿ“– gradle.build

implementation("io.jsonwebtoken:jjwt-api:0.11.5")
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5")

 

โœ… 4-1. RSA ๋ฐฉ์‹ (๋น„๋Œ€์นญํ‚ค ๊ธฐ๋ฐ˜)

โœ” ์ธ์ฆ ์„œ๋ฒ„(ex.auth-service)๋Š” ๊ฐœ์ธํ‚ค(Private Key)๋กœ JWT ์„œ๋ช…

โœ” ๊ฒ€์ฆ ์„œ๋ฒ„(ex.gateway)๋Š” ๊ณต๊ฐœํ‚ค(Public Key)๋กœ JWT ๊ฒ€์ฆ

 

๐Ÿ“– JWT ๋ฐœ๊ธ‰ (RSA ํ‚ค ์‚ฌ์šฉ)

@Component
public class JwtTokenProvider {
    private final KeyPair keyPair = {keyPair}; // RSA ํ‚ค ์Œ (๊ณต๊ฐœ ํ‚ค + ๊ฐœ์ธ ํ‚ค)
    
    public String createToken(String username, List<String> roles) {
        return Jwts.builder()
                .setSubject(username)
                .claim("roles", roles)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1์‹œ๊ฐ„ ์œ ํšจ
                .signWith(keyPair.getPrivate(), SignatureAlgorithm.RS256) // ๊ฐœ์ธ ํ‚ค๋กœ ์„œ๋ช…
                .compact();
    }

    public PublicKey getPublicKey() {
        return keyPair.getPublic(); // ๊ณต๊ฐœ ํ‚ค ๊ฒ€์ฆ ์„œ๋ฒ„์—๊ฒŒ ์ œ๊ณต
    }
}

 

๐Ÿ“– JWK Set ๊ณต๊ฐœ (Auth ์„œ๋ฒ„์—์„œ ์ œ๊ณต)

@RestController
@RequestMapping("/.well-known")
public class JwkSetController {
    private final JwtTokenProvider jwtTokenProvider;
    
    public JwkSetController(JwtTokenProvider jwtTokenProvider) {
        this.jwtTokenProvider = jwtTokenProvider;
    }

    @GetMapping("/jwks.json")
    public Map<String, Object> getJwks() throws Exception {
        PublicKey publicKey = jwtTokenProvider.getPublicKey();
        RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) publicKey)
                .keyID("my-key-id") // ํ‚ค ID (์ž„์˜ ๊ฐ’)
                .algorithm(JWSAlgorithm.RS256)
                .build();
        return new JWKSet(rsaKey).toJSONObject();
    }

}

 

โœ… 4-2. HS256 ๋ฐฉ์‹ (๋Œ€์นญํ‚ค ๊ธฐ๋ฐ˜)

โœ” ์ธ์ฆ ์„œ๋ฒ„์™€ ๊ฒ€์ฆ ์„œ๋ฒ„์— ๋™์ผํ•œ Secret key ์‚ฌ์šฉ.

 

๐Ÿ“– JWT ๋ฐœ๊ธ‰ (HS256 ํ‚ค ์‚ฌ์šฉ)

@Component
public class JwtTokenProvider {
    private final String SECRET_KEY = {secret-key}; // ์•ˆ์ „ํ•œ ์ €์žฅ ํ•„์š” (ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์‚ฌ์šฉ ๊ถŒ์žฅ)
    private final long EXPIRATION_TIME = 1000 * 60 * 60; // 1์‹œ๊ฐ„

    // JWT ์ƒ์„ฑ (HS256 ์‚ฌ์šฉ)
    public String createToken(String username, List<String> roles) {
        Claims claims = Jwts.claims().setSubject(username);
        claims.put("roles", roles);

        return Jwts.builder()
                   .setClaims(claims)
                   .setIssuedAt(new Date())
                   .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                   .signWith(SignatureAlgorithm.HS256, SECRET_KEY.getBytes())
                   .compact();
    }

    @SuppressWarnings("deprecation")
    public boolean validateToken(String token) {
        try {
            Jwts.parserBuilder()
                .setSigningKey(SECRET_KEY.getBytes())
                .build()
                .parseClaimsJws(token); // JWT์˜ ํ˜•์‹(Header.Payload.Signature ํ˜•ํƒœ์ธ์ง€) & ์„œ๋ช… & ๋งŒ๋ฃŒ ๊ฒ€์ฆ      

            return true;

        // } catch (ExpiredJwtException e) {
        //     System.out.println("โŒ ๋งŒ๋ฃŒ๋œ ํ† ํฐ์ž…๋‹ˆ๋‹ค!");
        // } catch (MalformedJwtException e) {
        //     System.out.println("โŒ ์ž˜๋ชป๋œ ํ˜•์‹์˜ ํ† ํฐ์ž…๋‹ˆ๋‹ค!");
        // } catch (SignatureException e) {
        //     System.out.println("โŒ ์„œ๋ช…์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ ํ† ํฐ์ž…๋‹ˆ๋‹ค!");
        } catch (Exception e) {
            return false;
        }
    }
    
}

 


โœ… 5. JWT ๊ฒ€์ฆ

Filter์„ ๋ณ„๋„๋กœ ์ž‘์„ฑํ•˜์—ฌ @Configuration์—์„œ ์ ์šฉํ•˜๊ณ ,

์œ„ JwtTokenProvider.validateTokenํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ jwt ํ† ํฐ์„ ๊ฒ€์ฆํ•˜์—ฌ ์š”์ฒญ์„ ํ†ต๊ณผ์‹œํ‚ค๊ฑฐ๋‚˜ ์ฐจ๋‹จํ•œ๋‹ค.

๐Ÿ” filter๋ž€?

JWT ์ธ์ฆ์—์„œ ํ•„ํ„ฐ(Filter)๋Š” HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๊ฐ€๋กœ์ฑ„์„œ ํŠน์ • ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ. 

 

ํ‚ค ์ƒ์„ฑ ๋ฐฉ์‹์— ๋”ฐ๋ผ ์ œ๊ณต, ๊ฒ€์ฆ ๋ฐฉ์‹์ด ๋‹ค๋ฅด๋‹ค!! ๊ฒ€์ฆ ๋ฐฉ์‹์€ ์•„๋ž˜ ์ฝ”๋“œ ์ฐธ๊ณ 

๐Ÿ”— Spring Security ( ์ธ์ฆ ๊ตฌํ˜„ ๋ฐฉ์‹ ์ฐธ๊ณ !)

 

โญ ํ† ํฐ ๊ฒ€์ฆ ์œ„์น˜

๋ณดํ†ต Spring Security์—์„œ ๊ฒ€์ฆ ํ•˜๋Š”๋ฐ Gateway๋„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ๋‘˜ ์ค‘ ํ•˜๋‚˜์—์„œ๋งŒ Filter๋กœ JWT ๊ฒ€์ฆ์„ ํ•˜๋ฉด ๋œ๋‹ค.

  • Gateway: JwtGatewayFilterFactory ์ž‘์„ฑ.Gateway์—์„œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ(์š”์ฒญ์ด ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค๋กœ ๋„˜์–ด๊ฐ€๊ธฐ ์ „) JWT ํ† ํฐ์„ ๊ฒ€์ฆ, ์š”์ฒญ์ด ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค๋กœ ๋„˜์–ด๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. 
  •  Spring Security: JwtAuthenticationFilter ์ž‘์„ฑ. ์š”์ฒญ์ด ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค์— ๋„๋‹ฌํ•œ ํ›„, ํ•ด๋‹น ์š”์ฒญ์ด ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์— ์˜ํ•ด ์ด๋ฃจ์–ด์กŒ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

โœ… 6. Key์™€ JWT ๊ด€๋ฆฌ

ํ† ํฐ ์ƒ์„ฑ์— ์‚ฌ์šฉํ•˜๋Š” โ€œKeyโ€์™€ ๊ฒฐ๊ณผ๋ฌผ์ธ JWT(AccessToken, RefreshToken)์˜ ์•ˆ์ „ํ•œ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค!!

 

๐ŸŒŸ ์•„๋ž˜์˜ ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•์„ ๋ชจ๋‘ ์ ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค!! ๋ณธ์ธ์˜ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ ์šฉํ•  ๊ฒƒ.

ํ•„์ˆ˜๋ผ๊ณ  ์ƒ๊ฐ ๋˜๋Š” ๊ฒƒ์—๋Š” ๋ฒˆํ˜ธ๋’ค์— โญ ๋ถ™์ž„!!

 

โœ… 6-1. Key ๊ด€๋ฆฌ

1๏ธโƒฃ โญSecret Key๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€ํ•˜๊ธฐ

  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜(.env) ๋˜๋Š” Key Management System(KMS) ์‚ฌ์šฉ
  • ์†Œ์Šค ์ฝ”๋“œ์— ์ง์ ‘ ๋…ธ์ถœ โŒ

 

2๏ธโƒฃ Secret Key ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ณ€๊ฒฝ (Key Rotation)

  • ์ •๊ธฐ์ ์œผ๋กœ ์ƒˆ๋กœ์šด ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ธฐ์กด ํ‚ค๋ฅผ ํ๊ธฐํ•˜๋Š” Key Rotation ์ ์šฉ
  • ์˜ˆ์ „ ํ‚ค๋กœ ์„œ๋ช…๋œ JWT๋Š” ์ผ์ • ๊ธฐ๊ฐ„ ๋™์•ˆ๋งŒ ํ—ˆ์šฉ(๊ทธ๋ ˆ์ด์Šค ๊ธฐ๊ฐ„)

 

3๏ธโƒฃ ๋‹ค์ค‘ Secret Key ๊ด€๋ฆฌ (ํ‚ค ๋ฒ„์ „ ์ ์šฉ)

  • ์˜ˆ: "kid"(Key ID) ํ•„๋“œ๋ฅผ JWT์— ์ถ”๊ฐ€ํ•˜์—ฌ,
    ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ‚ค๋ฅผ ์šด์˜ํ•˜๋ฉด์„œ ์ ์ง„์ ์œผ๋กœ ๊ต์ฒด ๊ฐ€๋Šฅ

 

4๏ธโƒฃ MSA ํ™˜๊ฒฝ์—์„œ๋Š” ์„œ๋น„์Šค๋ณ„ Secret Key ๋ถ„๋ฆฌ

  • ํ•˜๋‚˜์˜ ํ‚ค๋ฅผ ๋ชจ๋“  ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉ โŒ
  • ๊ฐ ์„œ๋น„์Šค๋ณ„๋กœ ๋‹ค๋ฅธ Secret Key ์‚ฌ์šฉ โ†’ ํŠน์ • ์„œ๋น„์Šค๋งŒ ์œ„ํ—˜ํ•ด์ง

 

5๏ธโƒฃ JWT ๋Œ€์ฒด ๋ฐฉ๋ฒ• ๊ณ ๋ ค (Opaque Token)

  • ์„œ๋ฒ„์—์„œ ์„œ๋ช… ๊ฒ€์ฆ ์—†์ด DB์—์„œ ์ง์ ‘ ํ† ํฐ์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ์‹ ๊ณ ๋ ค
  • JWT๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ฒ€์ฆ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, Secret Key ์†์ƒ์˜ ์œ„ํ—˜์ด ํฌ๊ธฐ ๋•Œ๋ฌธ

 

6๏ธโƒฃ Key ์œ ์ถœ ๊ฐ์ง€๋ฅผ ์œ„ํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง(๋กœ๊ทธ ๋ถ„์„)

  • ๋น„์ •์ƒ์ ์œผ๋กœ ๋งŽ์€ JWT ๋ฐœ๊ธ‰ ์š”์ฒญ, ์œ ํšจํ•˜์ง€ ์•Š์€ JWT ์‹œ๋„ ๊ฐ์ง€ ๋“ฑ

 

โœ… 6-2. JWT ๊ด€๋ฆฌ

1๏ธโƒฃโญAccess Token์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€ํ•˜๊ธฐ

 

2๏ธโƒฃ โญRefresh Token์˜ ์ด์šฉ

  • Access Token์„ ์งง๊ฒŒ ์„ค์ •ํ•˜๊ณ  Refresh Token์„ ํ™œ์šฉ
  • Refresh Token์„ DB์—์„œ ๊ด€๋ฆฌํ•˜๊ณ , ํƒˆ์ทจ ์‹œ ์ „์ฒด ๋ฌดํšจํ™” ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค๊ณ„
  • Refresh Token์„ ์‚ฌ์šฉํ•  ๋•Œ DB/redis์— ์ €์žฅ๋œ ๊ฒƒ๊ณผ ๊ฐ™์€์ง€ ํ•œ๋ฒˆ ๋” ๊ฒ€์ฆ

 

3๏ธโƒฃ ํ† ํฐ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ ์ด์šฉ

  • Redis ๊ฐ™์€ DB์— ์ €์žฅ, ์ด๋ฅผ ๋งŒ๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์œผ๋กœ์จ ํ•ด๋‹น ํ† ํฐ์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋„๋ก ํ•œ๋‹ค.
  • ๋กœ๊ทธ์•„์›ƒ ์—”๋“œํฌ์ธํŠธ ๋˜๋Š” ํƒˆ์ทจ ์˜์‹ฌ ์‹œ ์ ์šฉ.

 

โŒ ๋‹จ์ : ๋งค๋ฒˆ ์š”์ฒญ๋งˆ๋‹ค DB๋ฅผ ์กฐํšŒํ•ด์•ผ ํ•จ (์„ฑ๋Šฅ ๋ถ€๋‹ด ๐Ÿ˜ข)
 โœ”  ๋Œ€์•ˆ: 2๏ธโƒฃ Refresh Token์˜ ์ด์šฉ

 

4๏ธโƒฃ Token์— ์‚ฌ์šฉ์ž์˜ IP ๋‹ด์•„์„œ ๊ฒ€์ฆ

  • ๊ธฐ์กด์— ๋ฐœ๊ธ‰๋œ IP์ฃผ์†Œ์™€ ๋‹ค๋ฅธ IP์ฃผ์†Œ๊ฐ€ ํƒ์ง€๋˜์—ˆ๋‹ค๋ฉด ํ•ด๋‹น ํ† ํฐ์„ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ๋“ฑ๋กํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ค์‹œ ๋กœ๊ทธ์ธ์„ ์œ ๋„ ํ•œ๋‹ค.
  • ํƒˆ์ทจ๋œ ํ† ํฐ์— ๋Œ€ํ•œ ๋Œ€์‘.

 

โŒ๋‹จ์ : IP๋Š” ๋ณ€ํ•  ์ˆ˜ ์žˆ์Œ (ํ”„๋ก์‹œ, VPN ์‚ฌ์šฉ, ์œ ๋™ IP, ๋ชจ๋ฐ”์ผ ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ ๋“ฑ) -> IP ๋ณ€ํ•˜๋ฉด ์ •์ƒ ์‚ฌ์šฉ์ž๋„ ๋กœ๊ทธ์•„์›ƒ ๋จ.
 โœ” ๋Œ€์•ˆ:

  • IP์™€ User-Agent ์ •๋ณด๋ฅผ ์„œ๋ฒ„์—์„œ ์„ธ์…˜ ํ˜•ํƒœ๋กœ ๋”ฐ๋กœ ๊ด€๋ฆฌ
  • ์š”์ฒญ ์‹œ IP๊ฐ€ ๋‹ค๋ฅด๋ฉด ์ถ”๊ฐ€ ์ธ์ฆ (ex. OTP) ์š”๊ตฌ
  • Refresh Token ์žฌ๋ฐœ๊ธ‰ ์‹œ IP ๊ฒ€์ฆ

 

5๏ธโƒฃ ์‚ฌ์šฉ์ž ์ •๋ณด ์—…๋ฐ์ดํŠธ (๊ถŒํ•œ ๋ณ€๊ฒฝ ๋“ฑ)

  • JWT๋Š” ๋ฐœ๊ธ‰ ํ›„ ์ˆ˜์ • ํ•  ์ˆ˜ ์—†๋‹ค.

 

โœ” ๋Œ€์•ˆ:

  • Access Token ๋Œ€์‹  Opaque Token(์„œ๋ฒ„ ์ €์žฅํ˜• ํ† ํฐ) ํ™œ์šฉ
  • Refresh Token ์žฌ๋ฐœ๊ธ‰ ์‹œ์ ์— ์ •๋ณด ๋ฐ˜์˜
  • Token ๋ฒ„์ „ ํ•„๋“œ ์ถ”๊ฐ€ ํ›„, Refresh ์‹œ ๊ฒ€์ฆ

 

'study > ๋ณด์•ˆ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Keystore์™€ Truststore  (0) 2025.04.10
SSL์ด๋ž€? (Secure Sockets Layer)  (0) 2025.03.24
์ €์žฅ์†Œ ๋น„๊ต  (0) 2024.12.01
๋ฐฉํ™”๋ฒฝ/IDS/IPS  (0) 2024.03.12
CNAPP (CWPP/SCPM/CIEM)  (0) 2024.03.12