본문 바로가기
WEB/Back-end

JWT(Json Web Token)

by 최새벽 2024. 10. 15.

json web token

 

인증이 성공한 사용자에게 특수한 문자열(토큰)을 전송

api 호출할때 이 문자열을 읽어서 해당 request가 정상적인지 확인 

 

Header: 토큰 타입과 알고리즘 의미

Payload: 이름(name)과 값(value)의 쌍을 cliam이라 하고 cliams를 모아둔 객체를 의미

Signature 헤더의 인코딩 값과 정보의 인코딩 값을 합쳐 비밀 키로 해시 함수로 처리된 결과

 

https://jwt.io/

 

JWT.IO

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

jwt.io

 

 

JWT사용을 위해서는 직접 구현할 수도 있고 라이브러리를 이용해서 개발할 수 있는데, 주로 라이브러리를 이용함.

 

 

mavenrepository에서 jjwt 라이브러리 api랑 impl 두가지 버전을 build.gradle에 추가

implementation 'io.jsonwebtoken:jjwt-gson:0.12.6'
implementation 'io.jsonwebtoken:jjwt-impl:0.12.6'
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'

 

패키지명/security/util 에 JWTUtil 클래스 만들기

 

 

 

[토큰 생성 및 인증]

package org.zerock.club.security.util;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClaims;
import io.jsonwebtoken.impl.DefaultJws;
import io.jsonwebtoken.impl.DefaultJwt;
import lombok.extern.log4j.Log4j2;

import java.time.ZonedDateTime;
import java.util.Date;

@Log4j2
public class JWTUtil {
    private String secretKey = "zerock12345678zerock123456789012";

    private long expire = 60*24*30;

    public String generateToken(String content) throws Exception {
        return Jwts.builder()
                .setIssuedAt(new Date())
                .setExpiration(Date.from(ZonedDateTime.now().plusMinutes(expire).toInstant()))
                .claim("sub", content)
                .signWith(SignatureAlgorithm.HS256, secretKey.getBytes("UTF-8"))
                .compact();
    }

    public String validateAndExtract(String tokenStr) throws Exception{
        String contentValue = null;
        try {
            DefaultJwt defaultJws = (DefaultJws) Jwts.parser()
                    .setSigningKey(secretKey.getBytes("UTF-8")).build().parseClaimsJws(tokenStr);
            log.info(defaultJws);
            log.info(defaultJws.getBody().getClass());
            DefaultClaims claims = (DefaultClaims) defaultJws.getBody();
            log.info("-----------------");
            contentValue = claims.getSubject();
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            contentValue = null;
        }
        return contentValue;
    }

}

 

[테스트 코드]

package org.zerock.club.security;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.zerock.club.security.util.JWTUtil;

public class JWTTests {
    private JWTUtil jwtUtil;

    @BeforeEach
    public void testBefore(){
        System.out.println("testBefore..............");
        jwtUtil = new JWTUtil();
    }

    @Test
    public void testEncode() throws Exception{
        String email = "user95@zerock.com";
        String str = jwtUtil.generateToken(email);
        System.out.println(str);
    }

}

 

테스트 코드 실행결과 나오는 토큰 

 

토큰 디코딩 하면 원래 들어간 값 나옴

 

 

- cors 필터 많이 사용하면 느려지므로 꼭 필요할때만 사용하기

- 토큰 만료 되면 재발급해주는 프로세스 필요함

'WEB > Back-end' 카테고리의 다른 글

(N:1) 다대일 관계 처리하기(SpringBoot)  (0) 2024.10.15
@EnableWebSecurity(SpringBoot)  (0) 2024.10.15
Spring Framework 및 API 개발 개요  (1) 2024.10.15
Spring Security(SpringBoot)  (0) 2024.10.15
EntityGraph (SpringBoot)  (0) 2024.10.15