
이번 포스트에서는 Spring Boot를 기반으로 JWT(Json Web Token)를 이용한 로그인 인증 기능을 구현하는 과정을 단계별로 정리합니다.
src/
└─ com.ccp.simple
├─ controller
│ └─ AuthController.java
├─ security
│ └─ JwtTokenProvider.java
├─ config
│ └─ SecurityConfig.java
├─ service
│ └─ UserService.java
└─ dto
└─ LoginRequestDto.java
JWT (JSON Web Token)는 사용자의 인증 정보를 안전하게 전달하기 위한 토큰 기반 인증 방식입니다.
✅ 특징
클라이언트는 받은 토큰을 저장 : 로컬 스토리지 / 세션 스토리지 / 쿠키 등에 저장
인증이 필요한 요청마다 토큰을 같이 전송
GET /api/me HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
서버는 요청 시 토큰을 검증
JwtTokenProvider.validateToken()으로 유효성 체크
토큰이 유효하면 SecurityContext에 사용자 정보 설정
이후 컨트롤러 등에서 Authentication 객체로 사용자 정보 사용 가능
// JwtTokenProvider.java
@Component
public class JwtTokenProvider {
private final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
private final long validityInMilliseconds = 3600000; // 1시간
public String createToken(String userId) {
Claims claims = Jwts.claims().setSubject(userId);
Date now = new Date();
Date expiry = new Date(now.getTime() + validityInMilliseconds);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(expiry)
.signWith(key)
.compact();
}
public boolean validateToken(String token) {
try {
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}
public String getUserId(String token) {
return Jwts.parserBuilder().setSigningKey(key).build()
.parseClaimsJws(token).getBody().getSubject();
}
}
// SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.headers(headers -> headers.frameOptions().disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/h2-console/**", "/api/login", "/login.html").permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
/h2-console/**, /api/login 경로는 인증 없이 접근 가능하도록 허용합니다.
// AuthController.java
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class AuthController {
private final UserService userService;
private final JwtTokenProvider jwtTokenProvider;
@PostMapping("/login")
public String login(@RequestBody LoginRequestDto request, HttpServletResponse response) {
boolean valid = userService.validateUser(request.getUserId(), request.getUserPassword());
if (valid) {
String token = jwtTokenProvider.createToken(request.getUserId());
response.setHeader("Authorization", "Bearer " + token);
return "Login successful";
} else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return "Invalid credentials";
}
}
@GetMapping("/me")
public String currentUser(Authentication authentication) {
if (authentication == null) {
return "No Authentication found";
}
return "Current User ID : " + authentication.getPrincipal();
}
}
✔️ 1) 로그인 요청 (POST)
URL: http://localhost:8080/api/login

✔️ 2) 인증된 사용자 정보 요청 (GET)
URL: http://localhost:8080/api/me

퍼가요~♡