✅ 서론 - JWT 인증 방식과 리프레시 토큰이 필요한 이유
✅ 본론 - 스프링부트에서 리프레시 토큰 적용 방법 (구현 코드 포함)
✅ 결론 - 리프레시 토큰을 활용한 인증 시스템의 장점과 확장 가능성
1️⃣ 서론: JWT 인증 방식과 리프레시 토큰이 필요한 이유
🔹 JWT 기반 인증 방식의 문제점
- **Access Token(엑세스 토큰)**은 만료 기한이 있어 일정 시간이 지나면 다시 로그인해야 함
- 보안 강화를 위해 토큰 만료 시간을 짧게 설정하면, 사용자가 불편해짐
- 한 번 발급된 JWT는 변경 불가능(Stateless), 만료되면 새로 로그인해야 함
🔹 리프레시 토큰(Refresh Token)이란?
- Access Token이 만료되었을 때 새로운 토큰을 발급받기 위해 사용하는 토큰
- 보통 Access Token보다 긴 유효기간을 가짐
- Refresh Token이 유효하면, 사용자는 다시 로그인할 필요 없이 자동으로 Access Token을 갱신 가능
✅ 즉, 리프레시 토큰을 사용하면 보안성을 유지하면서도 사용자 경험을 개선할 수 있음!
2️⃣ 본론: 스프링부트에서 리프레시 토큰 적용 방법
🔹 1. JWT 관련 의존성 추가
📌 Spring Boot 프로젝트의 pom.xml에 JWT 관련 라이브러리를 추가.
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.11.5</version>
</dependency>
🔹 2. JWT 토큰 생성 & 검증을 위한 유틸 클래스 작성
📌 JwtTokenProvider.java (JWT 생성 & 검증)
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;
public class JwtTokenProvider {
private final Key secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
private final long ACCESS_TOKEN_EXPIRATION = 1000 * 60 * 15; // 15분
private final long REFRESH_TOKEN_EXPIRATION = 1000 * 60 * 60 * 24 * 7; // 7일
// 🔹 Access Token 생성
public String generateAccessToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + ACCESS_TOKEN_EXPIRATION))
.signWith(secretKey)
.compact();
}
// 🔹 Refresh Token 생성
public String generateRefreshToken() {
return Jwts.builder()
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + REFRESH_TOKEN_EXPIRATION))
.signWith(secretKey)
.compact();
}
// 🔹 토큰 검증 메서드
public boolean validateToken(String token) {
try {
Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}
// 🔹 토큰에서 사용자 정보 추출
public String getUsernameFromToken(String token) {
return Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}
✅ 이제 Access Token & Refresh Token을 생성할 수 있음!
✅ Access Token은 15분, Refresh Token은 7일로 설정
🔹 3. 로그인 API에서 JWT 발급 & 저장
📌 AuthController.java (로그인 API 구현)
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/auth")
public class AuthController {
private final JwtTokenProvider jwtTokenProvider = new JwtTokenProvider();
// 🔹 로그인 API
@PostMapping("/login")
public Map<String, String> login(@RequestParam String username) {
String accessToken = jwtTokenProvider.generateAccessToken(username);
String refreshToken = jwtTokenProvider.generateRefreshToken();
// 클라이언트가 Refresh Token을 보관하도록 응답에 포함
Map<String, String> response = new HashMap<>();
response.put("accessToken", accessToken);
response.put("refreshToken", refreshToken);
return response;
}
}
✅ 로그인 시 Access Token & Refresh Token을 함께 발급
🔹 4. 리프레시 토큰을 이용한 Access Token 갱신 API
📌 AuthController.java (토큰 갱신 API 추가)
@PostMapping("/refresh")
public Map<String, String> refresh(@RequestParam String refreshToken) {
// Refresh Token 검증
if (!jwtTokenProvider.validateToken(refreshToken)) {
throw new RuntimeException("Invalid Refresh Token");
}
// 새로운 Access Token 발급
String newAccessToken = jwtTokenProvider.generateAccessToken("User");
Map<String, String> response = new HashMap<>();
response.put("accessToken", newAccessToken);
return response;
}
3️⃣ 결론: 리프레시 토큰을 활용한 인증 시스템의 장점
🔹 리프레시 토큰 적용으로 얻는 장점
✅ 보안성 유지: Access Token을 짧게 유지하면서도 재로그인 없이 갱신 가능
✅ 사용자 경험 향상: 일정 시간 후에도 로그인 유지 가능
✅ 서버 부담 감소: Access Token은 Stateless하므로, 세션을 관리할 필요 없음
🔹 추가적으로 고려할 점
- Refresh Token 저장 방식:
- 보안 강화를 위해 DB나 Redis에 저장하는 방법도 고려
- 클라이언트가 Refresh Token을 보관하면 XSS/CSRF 공격 위험이 있음
- 만료된 Refresh Token 관리:
- Refresh Token이 탈취되었을 경우를 대비해 강제 로그아웃 기능 구현 필요
- OAuth2와 통합:
- OAuth2 인증 방식과 함께 적용하면 소셜 로그인 지원 가능
🎯 마무리: 스프링부트에서 리프레시 토큰을 적용하려면?
✅ JWT 기반 인증 방식을 사용하면 서버 부담 없이 인증 가능!
✅ Access Token은 짧게 설정하고, Refresh Token을 활용하면 사용자 경험 개선!
✅ 토큰 검증 API(/refresh)를 활용하여 토큰 갱신 자동화 가능!
🔥 이제 직접 코드 구현해보고, 보안 강화를 위해 Refresh Token을 DB에 저장하는 방법도 추가해보자! 🚀
'Springboot' 카테고리의 다른 글
🚀 스프링부트에서 사용자 권한(Role-Based Access Control, RBAC) 적용 방법 (0) | 2025.02.13 |
---|---|
🚀 Refresh Token 저장 방식 & 만료된 토큰 관리 방법 (0) | 2025.02.13 |
스프링부트 JWT란 무엇인가? 왜 사용할까? (0) | 2025.02.11 |
Springboot Mybatis 사용 방법 (0) | 2023.09.20 |
JUNIT을 활용한 테스트 코드 방법 및 예제 (0) | 2023.09.19 |