헤르메스 LIFE

[Spring Boot] Spring Boot + JWT ( JSON Web Token ) 테스트 본문

Spring Boot Framework

[Spring Boot] Spring Boot + JWT ( JSON Web Token ) 테스트

헤르메스의날개 2021. 1. 10. 01:12
728x90

개발환경

Spring Boot 2.2.4

JDK 1.8.0_202

REST

Postman : REST Client

 

목표

1. Spring Boot REST 환경

2. Log4j2 추가

3. JWT 기능 테스트

 


Spring Security를 준비하면서, JWT ( JSON Web Token ) 에 대해 테스트를 해봤습니다.

 

기존 프로젝트( hermeslog.tistory.com/449?category=530345 )에 JWT 기능 테스트를 해봤습니다.

1. pom.xml 수정

        <!-- Security and JWT -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
import com.sample.service.UserService;
import com.sample.web.base.service.SecurityService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/")
@Slf4j
public class HomeController {

    @Autowired
    private UserService userService;

    @Autowired
    private SecurityService securityService;

    @GetMapping("")
    public Map<String, String> home() {

        Map<String, String> res = userService.getMessage();

        return res;
    }

    @GetMapping("security/generate/token")
    public Map<String, Object> generateToken(@RequestParam String subject) {
        String token = securityService.createToken(subject, 1000 * 60 * 60 * 24L);    // 24시간
        Map<String, Object> map = new HashMap<>();
        map.put("userid", subject);
        map.put("token", token);
        return map;
    }

    @GetMapping("security/get/subject")
    public String getSubject(@RequestParam String token) {
        String subject = securityService.getSubject(token);
        return subject;
    }
}
public interface SecurityService {
    String createToken(String subject, long ttlMillis);

    String getSubject(String token);
}
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Service;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

@Service
public class SecurityServiceImpl implements SecurityService {

    public static final String secretKey = "4C8kum4LxyKWYLM78sKdXrzbBjDCFyfX";

    @Override
    public String createToken(String subject, long ttlMillis) {
        if (ttlMillis == 0) {
            throw new RuntimeException("토큰 만료기간은 0 이상 이어야 합니다.");
        }

        // HS256 방식으로 암호화 방식 설정
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secretKey);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        JwtBuilder builder = Jwts.builder()
                .setSubject(subject)                                               // User를 구분할 수 있는 값.
                .signWith(signatureAlgorithm, signingKey);

        long nowMillis = System.currentTimeMillis();
        builder.setExpiration(new Date(nowMillis + ttlMillis));
        return builder.compact();
    }

    @Override
    public String getSubject(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
                .parseClaimsJws(token).getBody();

        return claims.getSubject();
    }

    public String get(String token, String key) {
        String value = Jwts.parser()
                .setSigningKey((DatatypeConverter.parseBase64Binary(secretKey)))
                .parseClaimsJwt(token)
                .getBody()
                .get(key, String.class);

        return value;
    }

}

 

Postman 을 이용한 테스트

GET 방식

localhost:8090/security/generate/token?subject=admin

생성된 Token에 대해 확인 테스트

http://localhost:8090/security/get/subject?token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTYxMDI5NDM1MH0.4ZvvF_T6E5OFgPsdXTC-_V7-z0vrljWMf17tJODkSGA

 

JWT 홈페이지( jwt.io/ ) 에 접속하시면

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

토큰을 Decoded 할 수 있습니다.

 

 

728x90