IT/JAVA

Java로 JWT(JSON Web Token) 인증 구현

KeepGooing 2024. 11. 26. 14:23
반응형

Java로 JWT(JSON Web Token) 인증 구현

 

1. 필요한 의존성 추가

먼저 JWT를 처리하기 위한 라이브러리를 프로젝트에 추가해야 합니다. 이 예제에서는 'jjwt' 라이브러리를 사용합니다.

    io.jsonwebtoken
    jjwt-api
    0.11.5


    io.jsonwebtoken
    jjwt-impl
    0.11.5
    runtime

    io.jsonwebtoken
    jjwt-jackson
    0.11.5
    runtime

2. JWT 유틸리티 클래스 구현

JWT를 생성하고 검증하는 메서드를 포함한 유틸리티 클래스를 구현합니다.


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;

public class JwtUtil {
    private static final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    private static final long EXPIRATION_TIME = 864_000_000; // 10 일

    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(key)
                .compact();
    }

    public static String extractUsername(String token) {
        return extractClaims(token).getSubject();
    }

    public static boolean validateToken(String token) {
        try {
            extractClaims(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private static Claims extractClaims(String token) {
        return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
    }
}

이 클래스는 토큰 생성, 사용자 이름 추출, 토큰 유효성 검증 등의 기능을 제공합니다.

3. 인증 서비스 구현

사용자 인증을 처리하고 JWT를 생성하는 서비스를 구현합니다.


public class AuthenticationService {
    public String authenticate(String username, String password) {
        // 여기에 실제 사용자 인증 로직을 구현합니다.
        // 예를 들어, 데이터베이스에서 사용자 정보를 확인하는 등의 작업을 수행합니다.
        if (isValidUser(username, password)) {
            return JwtUtil.generateToken(username);
        } else {
            throw new RuntimeException("Invalid credentials");
        }
    }

    private boolean isValidUser(String username, String password) {
        // 실제 사용자 검증 로직을 구현합니다.
        // 이 예제에서는 간단히 true를 반환합니다.
        return true;
    }
}
        

4. JWT 필터 구현

HTTP 요청을 가로채고 JWT를 검증하는 필터를 구현합니다.


import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtAuthenticationFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String token = httpRequest.getHeader("Authorization");

        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            if (JwtUtil.validateToken(token)) {
                String username = JwtUtil.extractUsername(token);
                // 여기에서 사용자 인증 정보를 설정합니다.
                // 예: SecurityContextHolder.getContext().setAuthentication(...)
            }
        }

        chain.doFilter(request, response);
    }
}
        

5. 사용 예시

구현한 JWT 인증 시스템을 사용하는 예시입니다.


public class AuthController {
    private AuthenticationService authService = new AuthenticationService();

    public String login(String username, String password) {
        try {
            String token = authService.authenticate(username, password);
            return "Login successful. Token: " + token;
        } catch (RuntimeException e) {
            return "Login failed: " + e.getMessage();
        }
    }

    public String accessProtectedResource(String token) {
        if (JwtUtil.validateToken(token)) {
            String username = JwtUtil.extractUsername(token);
            return "Access granted for user: " + username;
        } else {
            return "Access denied: Invalid token";
        }
    }
}
        

6. 보안 고려사항

  • 비밀 키를 안전하게 관리하세요. 프로덕션 환경에서는 환경 변수나 보안 저장소를 사용하여 키를 관리해야 합니다.
  • 토큰의 만료 시간을 적절히 설정하세요. 너무 길게 설정하면 보안 위험이 증가할 수 있습니다.
  • HTTPS를 사용하여 토큰을 안전하게 전송하세요.
  • 필요한 경우 토큰 갱신 메커니즘을 구현하세요.
  • 토큰에 민감한 정보를 포함하지 마세요.

결론

Java를 사용하여 JWT 인증을 구현하는 것은 상대적으로 간단하며, 강력한 보안 기능을 제공합니다. 이 예제를 기반으로 실제 애플리케이션의 요구사항에 맞게 확장하고 커스터마이즈할 수 있습니다. JWT를 사용함으로써 서버의 상태를 유지하지 않고도 안전하게 사용자를 인증할 수 있으며, 마이크로서비스 아키텍처에서도 효과적으로 활용할 수 있습니다.

JWT 인증은 현대 웹 애플리케이션에서 널리 사용되는 방식입니다. 그러나 모든 보안 시스템과 마찬가지로, 적절한 구현과 지속적인 관리가 중요합니다. 보안 업데이트를 주기적으로 확인하고, 최신 보안 권장사항을 따르는 것을 잊지 마세요.

 

반응형