JWT 간단 응용 예제

Spring Boot와 JWT를 활용한 인증 시스템 구현

1. Maven 의존성 추가



<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.4.0</version>
</dependency>

2. JWT 유틸리티 클래스 (TokenUtil)


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class TokenUtil {

    private static final long TOKEN_EXPIRE_TIME = 30 * 24 * 60 * 60;
    private static final String JWT_SECERT = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY=";
    public static final String TOKEN_ID = "tokenId";

    public static String createToken(Map claims, Long time) {
        SignatureAlgorithm algorithm = SignatureAlgorithm.HS256;
        Date now = new Date(System.currentTimeMillis());

        SecretKey key = generateKey();
        long nowMillis = System.currentTimeMillis();

        JwtBuilder builder = Jwts.builder()
                .setClaims(claims)
                .setId(TOKEN_ID)
                .setIssuedAt(now)
                .signWith(algorithm, key);

        if (time >= 0) {
            long expMillis = nowMillis + time;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        return builder.compact();
    }

    public static Claims verifyToken(String token) {
        SecretKey key = generateKey();
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(key)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }

    private static SecretKey generateKey() {
        String stringKey = JWT_SECERT;
        byte[] encodedKey = Base64.decodeBase64(stringKey);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    public static String generateToken(String openId, Integer userId) {
        Map map = new HashMap<>();
        map.put("userId", userId);
        map.put("openId", openId);
        return createToken(map, TOKEN_EXPIRE_TIME);
    }
}

3. JWT 필터 (TokenFilter)


import com.llh.chat.util.TokenUtil;
import io.jsonwebtoken.Claims;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class TokenFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String token = request.getHeader("authorization");
        Claims claims = TokenUtil.verifyToken(token);

        if (claims == null) {
            response.getWriter().write("토큰이 유효하지 않습니다.");
        } else {
            filterChain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
    }
}

4. 필터 빈 등록 설정 (BeanRegisterConfig)


import com.llh.chat.filter.TokenFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanRegisterConfig {

    @Bean
    public FilterRegistrationBean createFilterBean() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new TokenFilter());
        registration.addUrlPatterns("/user/hello");
        return registration;
    }
}

5. Controller 예제


@RestController
public class LoginController {
    @RequestMapping("/user/login")
    public String login() {
        String jwtToken = TokenUtil.generateToken("123", 456);
        return jwtToken;
    }

    @RequestMapping("user/hello")
    public String user() {
        return "hello JWT";
    }
}

6. Postman을 활용한 테스트 방법

다음 토큰을 Postman의 Authorization 헤더에 추가하여 요청합니다:

eyJhbGciOiJIUzI1NiJ9.eyJvcGVuSWQiOiIxMjMiLCJleHAiOjE2MDEwMjA0NTcsInVzZXJJZCI6NDU2LCJpYXQiOjE2MDEwMTc4NjUsImp0aSI6InRva2VuSWQifQ.ic0z-Iel2Mk4c0xluuk6AijvxgzZZqAktKNMin6N0SU

태그: Spring Boot jwt java filter authentication

6월 5일 23:35에 게시됨