1. 인증과 인가 개념
1) 인증(Authentication)과 인가(Authorization)
웹 애플리케이션에서는 보안이 중요한 요소이며, 사용자의 신원을 확인하고 접근 권한을 부여하는 과정이 필요합니다.
- 인증 (Authentication): 사용자가 누구인지 확인하는 과정
- 인가 (Authorization): 사용자가 특정 리소스에 접근할 수 있는 권한을 갖고 있는지 확인하는 과정
2) 기존의 세션 기반 인증 방식의 한계
기존의 웹 애플리케이션에서는 서버가 사용자 정보를 저장하고 관리하는 세션 기반 인증을 사용했습니다. 하지만, 다음과 같은 단점이 존재합니다.
- 확장성 문제: 사용자가 많아질수록 서버에서 세션을 관리하는 부담 증가
- 분산 시스템에서의 어려움: 여러 서버에서 동일한 세션 정보를 유지하기 어려움
- 쿠키 사용의 보안 문제: 클라이언트에서 쿠키를 조작할 위험 존재
이러한 문제를 해결하기 위해 토큰 기반 인증(Token-based Authentication) 이 등장했습니다.
2. JWT란?
1) JWT (JSON Web Token)의 개념
JWT는 JSON 포맷을 사용하여 정보를 안전하게 전송하는 방식으로, 인증과 권한 부여에 널리 사용됩니다.
2) JWT의 구조
JWT는 Header, Payload, Signature 세 부분으로 구성됩니다.
JWT 예제
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsInJvbGUiOiJVU0VSIn0.QpXyM9y0-Vfr1YNxQxqEOQExa8pmA5OPtyFk6JP3q8o
구성 요소 설명
Header | 토큰의 타입(JWT)과 해싱 알고리즘 (HS256 등) 포함 |
Payload | 사용자 정보 (userId, role 등)를 포함한 데이터 |
Signature | Header와 Payload를 비밀키로 서명하여 위변조 방지 |
JWT는 서버에서 인증 후 클라이언트에게 발급되며, 클라이언트는 이후 요청에서 JWT를 포함시켜 인증을 진행합니다.
3. JWT를 활용한 인증 시스템
1) JWT 인증 과정
JWT 인증 방식은 다음과 같은 흐름으로 이루어집니다.
- 클라이언트가 로그인 요청을 보냄
- 서버가 사용자 인증 후 JWT를 발급하여 클라이언트에 전달
- 클라이언트는 이후 요청에서 JWT를 포함하여 서버에 보냄
- 서버는 JWT를 검증하고 사용자 정보를 확인하여 응답 반환
2) Access Token과 Refresh Token
JWT를 사용할 때 Access Token과 Refresh Token을 함께 사용하는 경우가 많습니다.
- Access Token: 인증을 위한 토큰으로, 짧은 만료 시간을 가짐
- Refresh Token: Access Token이 만료되었을 때 재발급을 위한 토큰
이 방식을 사용하면 보안성을 강화하면서도 사용자 경험을 개선할 수 있습니다.
4. Spring Security + JWT 구현
1) JWT 생성 및 검증
Spring Boot와 Spring Security를 활용하여 JWT 인증을 구현할 수 있습니다.
(1) JWT 토큰 생성 코드
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtil {
private static final String SECRET_KEY = "your_secret_key";
public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 86400000))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
}
(2) JWT 검증 코드
public static Claims validateToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
2) Spring Security에서 JWT 적용
Spring Security에서 UsernamePasswordAuthenticationFilter를 확장하여 JWT 기반 인증을 적용할 수 있습니다.
JWT 필터 구현 예제
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
Claims claims = JwtUtil.validateToken(token.substring(7));
if (claims != null) {
String username = claims.getSubject();
Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(request, response);
}
}
5. JWT의 장점과 단점
✅ 장점
- 확장성: 세션 관리 없이 서버 확장이 가능함
- 보안성: 서명(Signature)으로 토큰 변조 방지
- 성능 향상: 서버에서 상태 저장을 하지 않으므로 빠른 인증 가능
❌ 단점
- 토큰 탈취 시 보안 문제: 탈취된 토큰은 유효기간이 끝날 때까지 사용 가능
- 토큰 크기 증가: 세션 기반 인증보다 클라이언트의 저장 부담이 있음
- 만료 후 재인증 필요: Refresh Token을 사용하여 재인증 로직을 구현해야 함
결론
JWT는 REST API 기반의 애플리케이션에서 널리 사용되는 인증 방식으로, 세션 기반 인증보다 확장성이 뛰어나지만, 보안에 대한 충분한 고려가 필요합니다. Spring Boot와 Spring Security를 활용하여 JWT 인증 시스템을 구축하면, 안전하면서도 성능 좋은 인증 시스템을 구현할 수 있습니다. 🚀
'모각코' 카테고리의 다른 글
[백엔드]비동기 처리와 메시지 큐 이해하기 (0) | 2025.02.12 |
---|---|
[백엔드]JPA 이해하기 (1) | 2025.02.10 |
[백엔드]RESTful API 이해하기 (0) | 2025.02.10 |
[백엔드]SQL 이해하기 (0) | 2025.01.29 |
[백엔드]자바 스프링부트 이해하기 (0) | 2025.01.29 |