이번 글에서는 Spring Boot + JWT 기반의 로그인 기능에 Refresh Token 기능을 추가하고,
토큰 재발급 및 로그아웃 처리까지 구현한 과정을 기록합니다.
user_info 테이블에 컬럼 추가)ALTER TABLE user_info ADD refresh_token VARCHAR(255);
저장 이유
| API 명 | Method | URL | 설명 |
|---|---|---|---|
| 로그인 | POST | /api/login | ID/PW 검증 후 토큰 발급 |
| 인증 테스트 | GET | /api/user/test | Access Token 유효성 검증 |
| 토큰 재발급 | POST | /api/refresh | Refresh Token으로 Access Token 재발급 |
| 로그아웃 | POST | /api/logout | Refresh Token 삭제 |
String refreshToken = jwtUtil.createRefreshToken(username);
userMapper.updateRefreshToken(username, refreshToken);
return Map.of(
"accessToken", accessToken,
"refreshToken", refreshToken
);
@PostMapping("/api/refresh")
public Map<String, String> refreshToken(@RequestBody Map<String, String> request) {
String refreshToken = request.get("refreshToken");
if (!jwtUtil.validateToken(refreshToken)) {
throw new RuntimeException("Refresh Token이 유효하지 않습니다.");
}
String username = jwtUtil.getUsername(refreshToken);
String savedRefreshToken = userMapper.findRefreshToken(username);
if (!refreshToken.equals(savedRefreshToken)) {
throw new RuntimeException("Refresh Token 불일치");
}
String newAccessToken = jwtUtil.createAccessToken(username);
return Map.of("accessToken", newAccessToken);
}
@PostMapping("/api/logout")
public void logout(@RequestBody Map<String, String> request) {
String refreshToken = request.get("refreshToken");
String username = jwtUtil.getUsername(refreshToken);
userMapper.updateRefreshToken(username, null);
}
json
{ "username": "testuser", "password": "1234" }
응답: Access Token + Refresh Token
css
Authorization: Bearer {accessToken}
json
{ "refreshToken": "발급받은_refresh_token" }
응답: 새 Access Token
json
{ "refreshToken": "발급받은_refresh_token" }
json
{ "refreshToken": "발급받은_refresh_token" }
mathematica
Refresh Token 불일치

다음 단계에서는: