jwt

jwt token 생성

원코드 2024. 9. 2. 18:14

JWT 토큰 암호화 알고리즘에는 HS256과 RS256이 주로 사용된다.

JWT 라이브러리의 암호화 알고리즘 기본값은 HS256 이므로 이에 맞게 secret key를 생성하자.

 

HS256(HMAC with SHA256) : 

원본 메시지와 공유된 메시지를 비교하여 변조 여부를 확인하는 것이 MAC(Message Authentication Code)이며, HMAC는 해시 메시지를 이용한다. SHA는 해시를 이용한 암호화 알고리즘으로 256길이의 해시값(64자리 문자열)을 생성하며, 단방향 암호화로 원본 복구가 불가능하다. 즉, SHA256 해시값을 이용하여 메시지 변조 여부를 확인하는 알고리즘이다.

 

따라서 JWT 토큰을 생성하기 위해선 SHA256 해시값을 HMAC 알고리즘에 적용하여 SECRET KEY를 생성해야 한다.

 

1. SHA256 해시값 생성 - open ssl 이용

소스 상에서 플레인 텍스트를 인코딩하여 생성하는 방법도 있지만, 간단하게 CLI를 이용하여 64자리 해시값을 생성해보자

git bash에 아래 명령어를 입력하면 랜덤한 문자값을 생성해준다.

openssl rand -hex 64

 

2. properties 또는 yml에 입력

jwt:
  secret: [생성한 해시값]

 

3. 토큰 생성

JwtProvider라는 클래스를 생성하여 토큰을 관리하자.

 

3-1. 생성자를 통해 yml에 입력한 값 주입.

private final SecretKey secretKey;
	
	public JwtProvider(@Value("${jwt.secret}") final String stringKey) {
	  this.secretKey = Keys.hmacShaKeyFor(stringKey.getBytes(StandardCharsets.UTF_8));
	}

 

Keys.hmacShaKeyFor() : key byte array를 기반으로 적절한 HMAC 알고리즘을 적용한 key 객체 생성.

 

3-2. 토큰 생성

public String createToken(Long memberId) {
		Date now = new Date();
		
		return Jwts.builder()
				//.setHeaderParam("type", "jwt") -> deprecation
				//.setIssuedAt(now)// -> deprecation
				//.setExpiration(now) -> deprecation
				//.signWith(secretKey, SignatureAlgorithm.HS256) -> deprecation
				.header().add("type", "jwt")
				.and()
				.claim("memberId", memberId)
				.issuedAt(now)
				.expiration(now)
				.signWith(secretKey)
				.compact();
	}

 

 

다른 개발 블로그들을 참고로 하다가 deprecation 된 것들이 많아서 아래 문서를 참고해 수정했다.

https://javadoc.io/static/io.jsonwebtoken/jjwt-api/0.12.3/index.html?io/jsonwebtoken/Claims.html

 

JJWT :: API 0.12.3 API

 

javadoc.io

 

3-3. 전체 코드

package com.tlog.backend.login;

import java.nio.charset.StandardCharsets;
import java.util.Date;

import javax.crypto.SecretKey;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

@Component
public class JwtProvider {
	
	
	private final SecretKey secretKey;
	
	public JwtProvider(@Value("${jwt.secret}") final String stringKey) {
	  this.secretKey = Keys.hmacShaKeyFor(stringKey.getBytes(StandardCharsets.UTF_8));
	}
	
	public String createToken(Long memberId) {
		Date now = new Date();
		
		return Jwts.builder()
				//.setHeaderParam("type", "jwt") -> deprecation
				//.setIssuedAt(now)// -> deprecation
				//.setExpiration(now) -> deprecation
				//.signWith(secretKey, SignatureAlgorithm.HS256) -> deprecation
				.header().add("type", "jwt")
				.and()
				.claim("memberId", memberId)
				.issuedAt(now)
				.expiration(now)
				.signWith(secretKey)
				.compact();
	}
 
}

 

3-4. 테스트 코드

package com.tlog.backend.login;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Random;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

@SpringBootTest
@TestPropertySource(locations = "classpath:application.yml")
public class JwtTest {

	@Value("${jwt.secret}")
	String secretKey;
	
	@Test
	@DisplayName("yml파일에서 secret 값을 읽어온다.")
	void secretKey_test() {
		assertThat(secretKey).isNotNull();
	}
	
	@Test
	void create_token_test() {
		//given
		Long memberId = new Random().nextLong();
		
		JwtProvider provider = new JwtProvider(secretKey);
		
		//when
		String token = provider.createToken(memberId);
		
		//then
		assertThat(token).isNotNull();
		
		System.out.println("token:"+token);
	}
	
}

 

 

참고 블로그 :

https://leffept.tistory.com/450

 

[JWT]JWT 사용시 주의할 점 & 문제점

안녕하세요, 오늘은 지난번 포스팅에 이어 JWT를 무턱대고 사용할 때 생기는 문제점과 주의해야할 점들에 대해서 이야기 해보겠습니다. JWT 사용시 주의할 점 시크릿 키의 설정 JWT의 가장 핵심적

leffept.tistory.com

https://ndarkness.tistory.com/30

 

[JWT] token secret key 생성

token 의 알고리즘을 HS256으로 하게 되면 secret key 가 256bit 보다 커야 한다. 영어 알파벳이 8bit 이니, 영어 32자로 만들면 되겠다. 랜덤한 key를 자동으로 만들어 주는 사이트가 있다. RandomKeygen - The Sec

ndarkness.tistory.com

https://erjuer.tistory.com/83

 

[JWT] 서명을 위한 알고리즘 HS256과 RS256

JWT를 정리하다보니 JWT에 주로 사용되는 암호화 알고리즘 HS256과 RS256에 대해 언급이 필요할 것 같아 정리를 한다. 암호화 알고리즘 내 자세하고 복잡한 암호화 로직이 있지만 그 부분은 다음,, 언

erjuer.tistory.com

https://happy-jjang-a.tistory.com/262

 

random secret key 생성(openssl rand)

개발 할때 여러가지 이유로 복잡도 있는 랜덤한 키(ex. JWT secretkey 생성)를 생성해줘야 하는 경우가 있다. 이럴때 적절한 키를 선정하기 애매할 때가 있는데 OpenSSL 명령어 한줄로 간단히 랜덤 키를

happy-jjang-a.tistory.com

https://velog.io/@junyoungs7/JWT-%EC%83%9D%EC%84%B1-%EB%B0%8F-%EA%B2%80%EC%A6%9D-%ED%85%8C%EC%8A%A4%ED%8A%B8

 

JWT 생성 및 검증 테스트

JWT 생성

velog.io

https://velog.io/@msung99/Spring-Security-Refresh-Token-Access-Token-%EC%9D%84-%EC%BD%94%EB%93%9C%EB%A1%9C-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EC%9E%90

 

Refresh Token, Access Token 을 활용한 로그인 코드구현

이전 JWT 설명에서 Access Token에 이은 Refresh Token 을 활용한 코드 구현방법을 다루겠다고 말씀드렸었습니다. 현 포스팅에서 그들의 코드 구현을 알아보도록 하겠습니다. 지난 포스팅 내용을 참고하

velog.io