JWT #2 실습

KimSeonGyu·2023년 8월 23일
post-thumbnail

JWT 요약

이전 포스팅에서 언급했든 JWT는 ~~~.~~~.~~~의 형태를 갖으며 순서대로 Header. payload. Signature 이다.
Header는 Signature를 해싱하기위한 알고리즘을 담고있고 payload는 서버와 클라이언트가 주고받는, 시스템에서 실제 사용될 정보, 데이터를 담있다. 마지막 signature는 서버에서 토큰의 유효성을 검사하는 문자열을 담고있다.

1. 프로젝트 생성

src
└── main
    ├── java
    │   └── com
    │       └── example
    │           ├── utils
    │           │   └── JwtProvider.java
    │  			├── controller
    │			│   └── HelloController.java
    │           └── Application.java
    └── resources

위와 같이 간단한 프로젝트를 설정해주었다.

의존성은 다음과같다

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'com.h2database:h2'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'


	implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
	implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
}

2. JwtProvider.java

package com.example.practicesecurity.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtProvider {

    public static String createToken(String userName, String key, long expireTimeMs) {
        Date now = new Date(System.currentTimeMillis());

        Claims claims = Jwts.claims();
        claims.put("user_name", userName);

        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date(System.currentTimeMillis()))  // 토큰 발행 시간
                .setExpiration(new Date(System.currentTimeMillis() + expireTimeMs)) // 토큰 만료시간
                .signWith(SignatureAlgorithm.HS256, key)  // 알고리즘 설정
                .compact();

    }


}

3. Controller

package com.example.practicesecurity.controller;

import com.example.practicesecurity.utils.JwtProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/api")
public class HelloController {
    @Value("${jwt.token.secret}")
    private String key;

    private Long expireTimeMs = 1000 * 60 * 60l;


    @PostMapping("/gettoken")
    public ResponseEntity<String> getToken() {
        String token = JwtProvider.createToken("userName", key, expireTimeMs);
        return ResponseEntity.ok(token);
    }


}

위에서 key 값을 application.yml 파일에 설정해 주었다.

jwt:
  token:
    secret: "secretKey"

4. 실행결과

컨트롤러에서 간단한게 http://localhost:8080/api/gettoken 이 주소로 이동하면 토큰이 발급되도록 설정하였다. 이때 유저의 아이디는 "userName"으로 설정했기 때문에 토큰을 base64에서 디코딩하면 아이디값이 올바르게 나오는지 확인해야한다.

크롬 확장프로그램인 Talend API tester에서 테스트를 진행해본결과 정상적으로 토큰이 발행되었다.

이제 이 토큰을 JWT 사이트에서 알고리즘설정이후 디코딩된 설정을 확인해보면 유저 이름값에 컨트롤러에서 작성한 userName 이 올바르게 디코딩된것이 확인가능하다.

iat는 "Issued At"의 약자로 토큰이 발급된 시간이다. iat 값인 1692800727은 UNIX 타임스탬프로 변환하면 2023년 8월 23일 23시 25분 27초를 나타낸다.

exp는 "Expiration Time"의 약자로 토큰의 만료 시간이다.
exp 값인 1692804327은 UNIX 타임스탬프로 변환하면 2023년 8월 24일 00시 25분 27초를 나타낸다.

expireTimeMs 값은 밀리초(ms) 단위로 설정되므로, 1시간은 60분 × 60초 × 1000밀리초, 1일은 24시간 × 60분 × 60초 × 1000밀리초로 설정하명된다.

이번테스트에서 1시간으로 설정했기 때문에 올바르게 디코딩 값이 나왔다고 보면 된다.


profile
공부한 내용을 작성하는 블로그 입니다. 수정할 부분이 있다면 편하게 댓글 작성부탁드립니다!

0개의 댓글