๐ง Redis TTL
์ค๋์ JWT + Redis ์ธ์ฆ ์์คํ ์์ TTL (Time To Live)์ ๊ผญ ์ค์ ํด์ผ ํ๋ ์ด์ ์ ๋ํด์ ์์๋ณด๊ณ ์ ํ๋ค. ๐ง

๐ TTL (Time To Live)์ด๋?
TTL์ Redis์์ ๋ฐ์ดํฐ๊ฐ ์๋์ผ๋ก ์ญ์ ๋๋ ์๊ฐ์ ๋งํ๋ค.
์ฆ, Redis์ ๊ฐ์ ์ ์ฅํ ๋ ์ ํจ ๊ธฐ๊ฐ์ ํจ๊ป ์ค์ ํ๋ฉด, ๊ทธ ์๊ฐ์ด ์ง๋๋ฉด ์๋์ผ๋ก ์ญ์ ๋๋ ๊ฒ์ด๋ค.
redisTemplate.opsForValue().set("RT:userId", refreshToken, Duration.ofMillis(expirationMillis));
์์ ์ฝ๋์์ Duration.ofMillis(expirationMillis) ๋ถ๋ถ์ด TTL์ ์ค์ ํ๋ ์ฝ๋์ด๋ค.
๐ง ์ TTL์ ์ค์ ํด์ผ ํ ๊น?
1๏ธโฃ ๋ณด์ ๐
๋ง์ฝ ์ฌ์ฉ์์ ํ ํฐ์ด Redis์ ๋ฌด๊ธฐํ ์ ์ฅ๋๋ค๋ฉด,
๋ก๊ทธ์์ ํ์๋ ํ ํฐ์ด ๋จ์ ์์ด์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฟ๋ง ์๋๋ผ
์ ์์ ์ธ ์ฌ์ฉ์๊ฐ ํ์ทจํ ํ ํฐ์ ์ค๋ซ๋์ ์ฌ์ฉํ ์๋ ์์ ๊ฒ์ด๋ค.
๐๐ป ์ด๋ด ๋ TTL์ ์ค์ ํ๋ฉด, ํด๋น ์๊ฐ ์ดํ์ Redis์์ ์๋ ์ญ์ ๋๋ฏ๋ก ๋ณด์ ์ฌ๊ณ ๋ฅผ ์ค์ผ ์ ์๋ค.
2๏ธโฃ ์์คํ ์ฑ๋ฅ ๐โ๏ธ๐จ
Redis๋ ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฐ ์ ์ฅ์์ด๊ธฐ ๋๋ฌธ์ ์ค๋ซ๋์ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ์์๋๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ํ์์ด ๋ฐ์ํ๋ค.
๐๐ป ๋ฐ๋ผ์ TTL ์ค์ ์ ํตํด ์ฌ์ฉํ์ง ์๋ ์ค๋๋ ๋ฐ์ดํฐ๋ ์๋์ผ๋ก ์ญ์ ๋์ด Redis๊ฐ ๊ฐ๋ณ๊ฒ ์ ์ง๋๋๋ก ํด์ฃผ์ด์ผ ํ๋ค.
3๏ธโฃ ์ ์ง๋ณด์ ์ฉ์ด์ฑ ๐ ๏ธ
TTL์ ์ค์ ํด๋๋ฉด, ๋ณ๋๋ก ์ญ์ ๋ก์ง์ ์์ฑํ ํ์๊ฐ ์๋ค.
๐๐ป ๋ฐ๋ผ์ ์ฝ๋๊ฐ ํจ์ฌ ๊ฐ๊ฒฐํด์ง๊ณ , ์ค์๋ฅผ ์ค์ผ ์ ์๋ค.
๐ฅ JWT ๊ธฐ๋ฐ ์ธ์ฆ ์์คํ ์์์ TTL ์ค์ ์ ๋ต
JWT ๊ธฐ๋ฐ ์ธ์ฆ ์์คํ ์์๋ ์ฃผ๋ก ์๋ ๋ ๊ฐ์ง ํ ํฐ์ ์ฌ์ฉํ๋ค.
| ํ ํฐ ์ข ๋ฅ | ์ญํ | TTL ๊ถ์ฅ๊ฐ | Redis ์ ์ฅ ํ์์ฑ |
| ๐ Access Token | ์ฌ์ฉ์ ์ธ์ฆ / ์ธ๊ฐ ์ํ | โณ 15~30๋ถ | ๋ณดํต ์ ์ฅํ์ง ์์ |
| ๐ Refresh Token | AccessToken ์ฌ๋ฐ๊ธ์ฉ | โณ 7~14์ผ | Redis์ ์ ์ฅ + TTL ์ค์ |
๐ก ์ AccessToken์ Redis์ ์ ์ฅํ์ง ์์๊น?
1๏ธโฃ JWT์ ๋ณธ์ง์ Stateless ๊ตฌ์กฐ
JWT๋ ํ ํฐ ์์ฒด์ ๋ชจ๋ ์ธ์ฆ ์ ๋ณด (userId, ๊ถํ, ๋ง๋ฃ ์๊ฐ ๋ฑ)์ ๋ด๊ณ ์๋ค.
๋ฐ๋ผ์ ์๋ฒ๋ JWT๋ฅผ ๋ฐ์ ๋, ์๋ฒ์ ์ธ์ ์ด๋ DB๋ฅผ ์กฐํํ์ง ์์๋ ์ด ํ ํฐ์ด ์ ํจํ์ง ์์ฒด ๊ฒ์ฆ์ ํ ์ ์๋ค.
์ฆ, ์๋ฒ๋ ๊ธฐ์ต์ ํ์ง ์์๋ ํ ํฐ๋ง ๋ณด๊ณ ์ฒ๋ฆฌํ ์ ์์ผ๋ Redis์ ๋ฐ๋ก ์ ์ฅํ ํ์๊ฐ ์๋ค.
2๏ธโฃ AccessToken์ ์๋ช ์ด ์งง์
๋ณดํต AccessToken์ ์๋ช ์ ์งง๊ฒ ์ค์ ํด์, ํ์ทจ๋๋๋ผ๋ ํผํด๊ฐ ์ ํ์ ์ด๊ฒ ์ค๊ณ๋๋ค.
๋ฐ๋ผ์ TTL์ด ์งง๊ธฐ ๋๋ฌธ์ ์ค๋ ๋ณด๊ดํ ํ์๊ฐ ์์ผ๋ฏ๋ก ๊ตณ์ด ์ ์ฅํ์ง ์๊ณ , ์๋ฒ ์์ ๋ญ๋น๋ฅผ ์ค์ด๋ ๊ฒ์ด๋ค.
โ AccessToken์ Redis์ ์ ์ฅํ๋ ๊ฒฝ์ฐ
๋ฐ๋ก ์์์ AccessToken์ Redis์ ์ ์ฅํ ํ์๊ฐ ์๋ค๊ณ ํ์ง๋ง,, ๐
AccessToken์ Redis์ ์ ์ฅํด์ผ ํ๋ ๊ฒฝ์ฐ๋ ์กด์ฌํ๋ค.
๋ฐ๋ก ๋ธ๋๋ฆฌ์คํธ ์ฒ๋ฆฌ๋ฅผ ํด์ผํ๋ ๊ฒฝ์ฐ์ด๋ค.
์์ ๋ด์ฉ์ ์ฝ์ผ๋ฉด์,
๐ฌ "JWT๋ Stateless๋ผ์ ๋ก๊ทธ์์ ์ฒ๋ฆฌ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค๊ณ ๋ค์๋๋ฐ์?"
๋ผ๋ ์๋ฌธ์ ์ ํ์ผ๋ฉฐ AccessToken์ด ํ์ํ ๊ฒ์ด ์๋๊ฐ ์๊ฐํ์ ๋ถ๋ค์ด ์์ ๊ฒ์ด๋ค.
์ด๊ฑฐ์ ๋ํด์ ์ค๋ช ํ์๋ฉด,
์์น์ ์ผ๋ก๋ AccessToken์ด ๋ง๋ฃ๋๊ธฐ ์ ๊น์ง๋ ํ ํฐ์ด ์ ํจํ๊ธฐ ๋๋ฌธ์
๋ก๊ทธ์์์ ํด๋ ํ ํฐ์ ๊ฐ์ง ์ฌ๋์ ๊ณ์ ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ๋๋ค. ๐จ
๊ทธ๋์ ํ์ํ ๊ฒ์ด ๋ธ๋๋ฆฌ์คํธ์ด๋ค.
๋ธ๋๋ฆฌ์คํธ ์ฒ๋ฆฌ๋ฅผ ํ๋ค๋ ๊ฒ์
1๏ธโฃ ๋ก๊ทธ์์ ์ ํด๋น AccessToken์ Redis์ ์ ์ฅํด๋๊ณ
2๏ธโฃ TTL์ AccessToken์ ๋จ์ ๋ง๋ฃ ์๊ฐ๊ณผ ๋์ผํ๊ฒ ์ค์ ํจ์ผ๋ก์จ
3๏ธโฃ ์ดํ ์์ฒญ์ด ๋ค์ด์์ ๋ ์ด ํ ํฐ์ด ๋ธ๋๋ฆฌ์คํธ์ ์๋์ง ํ์ธํด์ ๊ฑฐ์ ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ก๊ทธ์์์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด๋ค.
์๋ฅผ ๋ค์ด ์๋์ ๊ฐ์ด ์ค์ ํด๋ ์ ์๋ค.
public void blacklistAccessToken(String accessToken, long expirationMillis){
String tokenHash = DigestUtils.md5DigestAsHex(accessToken.getBytes());
redisTemplate.opsForValue().set("BL:" + tokenHash, "blacklisted", Duration.ofMillis(expirationMillis));
}
'๐ป๊ณต๋ถ ๊ธฐ๋ก > ๐ Backend' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [Backend] RedisConfig ์์ฑ: Redis ์ฐ๋ํ๊ธฐ (1) | 2025.06.29 |
|---|---|
| [Backend] RedisTemplate (1) | 2025.06.28 |
| [Backend] JWT (0) | 2025.06.21 |
| [Backend] Java 17 VS Java 21 (2) | 2025.06.17 |
| [Backend] CI ์ค์ ์์ distribution (0) | 2025.06.17 |