JWT 토큰 발급을 위한 Spring Boot 가이드

오늘날의 디지털 환경에서 데이터 전송 보안은 그 어느 때보다 중요합니다. JSON 웹 토큰(JWT)은 당사자 간에 정보를 안전하게 전송하기 위한 강력한 솔루션으로 등장했습니다. 노련한 개발자이든 Java 애호가이든 Spring Boot에서 JWT 토큰을 발행하는 방법을 이해하는 것은 매우 귀중한 기술입니다. 이 포스트에서는 Spring boot로 JWT토큰을 발급하는 것을 실습해볼겁니다. 이 포스트를 마칠 때쯤이면 웹 애플리케이션의 보안을 강화할 준비가 될 것입니다.

목차

1. JWT를 간단하게 알아보자
1.1 JWT 의 구조
2. Spring boot에서 JWT를 발급받아보자

1. JWT 를 사용하는 이유

JWT 는 JSON Web Token의 약자로, JSON 객체로 정보를 안전하게 전송하기 위한 개방형 표준입니다. 이 정보는 디지털 서명되어 있기 때문에 검증하고 신뢰할 수 있습니다. JWT는 일반적으로 인증 및 정보 교환에 사용됩니다.

JWT 는 JSON을 사용하기 때문에 XML을 사용하는 SAML과 다르게 복잡하지 않게 사용할 수 있다. 그리고 대부분의 프로그래밍 언어에서 JSON Parser를 지원하기 때문에 매핑도 쉽게 할 수 있습니다.

아래 사진을 보아도 XML을 사용하는 SAML과는 다르게 보다 간편합니다.

JWT
JWT

JWT는 다양한 정보를 담을 수 있는 PAYLOAD를 가지고 있어 다양한 목적으로도 사용할 수 있다.

JWT를 사용 용도는 사용자 로그인, API 인증, 권한 관리, 데이터 교환 등등 다양한 방면으로 사용하고 있습니다.

JWT는 간편하고 안전하며 확장 가능한 인증 및 정보 교환 방법을 제공합니다.
다양한 웹 애플리케이션에서 활용될 수 있는 유용한 기술로 사용되고 있습니다.

1.1 JWT 의 구조

JWT 는 Header, Payload, Signature로 구성되었습니다.

JWT는 여러 가지 장점을 제공합니다.

  • 컴팩트: JWT는 컴팩트하며 URL, POST 매개변수 또는 HTTP 헤더 내부를 통해 전송할 수 있습니다.
  • 독립형: 사용자에 대한 필요한 정보를 전달하여 여러 데이터베이스 조회를 피할 수 있습니다.
  • 보안: 비밀 또는 공개/개인 키 쌍을 사용하여 서명할 수 있으므로 데이터 무결성과 신뢰성이 보장됩니다.

Header는 JWT 에서 사용할 타입(typ)와 hash 알고리즘(alg)의 종류를 가지고있습니다.

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload는 clame이라는 것이 존재합니다. Payload에 담기는 정보의 조각을 클레임이라고 부릅니다.
clame의 종류는 크게 3가지를 가지고 있습니다.
등록된 clame, 공개 clame, 비공개 calme 3가지를 가지고 있습니다.

등록된 clame은 토큰에 대한 정보를 담기 위해 이미 정해진 clame들입니다.

공개 clame은 사용자 정의 clame으로, 공개용 정보를 위해 사용합니다. 충돌 방지를 위해 URI 포멧을 이용하며 사용합니다.

비공개 clame은 사용자 정의 calme으로 서버와, 클라이언트 사이의 임의의 정보를 저장합니다.

예시 )
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Signature은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 암호화 코드입니다.

Signature은 토큰을 인코딩 하거나 유효성 검증을 할 때 사용하는 고유한 코드입니다.
위에서 만든 Header,Payload의 값을 BASE64로 인코딩하고 인코딩한 비밀 키를 Header에 alg로 정의한 알고리즘으로 해싱합니다 이 값을 다시 BASE64로 인코딩하여 생성합니다.

2. Spring boot에서 JWT를 발급 받아 보자

JWT를 생성하기 위해서는 build.gradle 파일안의 dependencies 부분에 라이브러리 명을 추가하여 주어야 합니다.

implementation 'io.jsonwebtoken:jjwt-api:0.12.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.5'

Gradle을 재구성해줍니다.

재구성 이후 코드를 작성해 주었습니다.

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JWTbuilder{
//  JWT를 복호화 해줄 key를 testtest로 지정해 주었습니다.
    private static final String SecretKey = "testtesttesttesttesttesttesttest";

    public String JWT(){

//      JWT header의 값을 담을 Map을 만들어 주었습니다.
        Map<String, Object> header = new HashMap<>();

//      만들어진 Map타입을 가지고있는 header 변수에 key value 방식으로 typ(key)와 
//      JWT(value)를 넣어줍니다.
        header.put("typ", "JWT");


//      토큰의 유효기간 1000(밀리세컨드) * 60(초) * 3(분) 총 3분으로 토큰 유효시간을 
//      정하겠다는 뜻
        Long expTime = 1000 * 60L * 3L;
//      현재시간을 불러오기 위해 Date 클래스 호출합니다.
        Date ext = new Date();
//      ext의 시간을 현재 시간 + expTime 변수에 담겨있는 1800000ms를 추가해 줍니다.
        ext.setTime(ext.getTime() + expTime);

//      payload를 담을 Map을 만들어 주었습니다.
        Map<String, Object> payload = new HashMap<>();
//      Map 타입을 가지고있는 payload에 테스트 : 테스트입니다(key:value 방식) 을 넣어주었습니다.
        payload.put("테스트", "테스트입니다");
//      JWT 만들어주는 메소드를 호출합니다.
        String jwt = Jwts.builder()
//        헤더 설정
        .setHeader(header)
//        payload 설정
        .setClaims(payload)
//        subject설정
        .setSubject("test")
//        시간 설정
        .setExpiration(ext)
//        암호화 알고리즘 및 복호화 key 설정
        .signWith(SignatureAlgorithm.HS256,SecretKey.getBytes())
//        만들기
        .compact();
        return jwt;
    }

}

이제 만들어준 알고리즘을 사용하기 위해 웹으로 접속하여 볼 수 있게 Controller 클래스를 만들어주었습니다.

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

//컨트롤러로 지정하라는 어노테이션입니다.
@Controller

class testcontroller{
//  POST 방식으로 "/"으로 접속하였을 때 아래의 코드를 실행시켜라 라는 어노테이션입니다.
    @PostMapping("/")
    public String jwt_token_issued(){
//      JWT 토큰 생성을 위해 JWT 생성 메소드 밖에 있는 클래스를 호출합니다.
        JWTbuilder jtm = new JWTbuilder();
//      페이지에 접속 할 시 만들어두었던 JWT 토큰 생성 메소드를 리턴시켜줍니다.
        return JWTbuilder.jwt();
    }
}

코드를 작성해준 후 spring boot를 실행하여줍니다.

postman으로 post 요청을 localhost:8080으로 하게 되었을 때 생성된 토큰이 리턴되게 됩니다.

jwt.io 사이트에 생성한 jwt 토큰을 Encoded에 붙혀넣었을 때 작성한 header, payload 그대로 나오는걸
볼 수 있습니다.

지금 바로 Srping Boot 환경에서 NGINX Plus API Gateway를 통한 JWT 검증을 구현해보세요!

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required