JWT(Json Web Token)

GilLog·2021년 7월 14일
1

개념

목록 보기
16/19

🙆‍♂️ import 🙇‍♂️

JWT(JSON Web Token) 란?[ yoonbumtae (BGSMM)]

JWT란?[geunwoobaek.log]

JWT

JWT(JSON Web Token)JSON 객체를 사용하여 가볍고 자가수용적인 (self-contained) 방식으로 정보를 안전성 있게 전달해주기 위한 토큰이다.

JWT는 RFC7519 표준으로,

JSON 객체 형태당사자 간 정보를 안전하게 전송하기 위한 소형의 자체 포함 형식으로 정의된다.
당사자간에 전송할 Claim을 나타내는 URL에 안전(url-safe)압축 수단


JWT 구조

JWT의 구조Header, Payload, Signature 세 가지를 포함하는 구조를 준수해야한다.

[Base64Encoded(HEADER)].
[Base64Encoded(PAYLOAD)].
[Encoded(SIGNATURE)]

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpZCI6ImdpbGxvZyIsIm5hbWUiOiJHaWxsb2ciLCJpYXQiOjE1MTYyMzkwMjJ9.
_OqpMXmKk6ajncTx5zCcC4ZxQwoVJZKep0Hh-Aw5YRM

Header는 일반적으로 Token Type(typ)과,

사용중인 서명 Algorithm(alg)두 부분으로 구성된다.

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

Payload

PayloadToken에 담을 정보를 나타내며 Claim들을 포함한다.

ClaimPayload 한 부분 들을 의미하고,

name, value 한 쌍의 구조로 구성된다.

Claim에는 Reserved(등록된), Public(공개), Private(비공개) 세 가지 유형이 있다.

Reserved Claim

Reserved Claim유용하고 상호 운용 가능한 제공을 위해 권장되는 미리 정의된 Claim 집합이다.

예시는 아래 표와 같다.

Claim약어의미
Issueriss발행자
Expirationexp만료시간
Subjectsub주제
Audienceaud대상자
{
    "iss": "gillog",
    "exp": "1485270000000",
    "aud": "user",
    "sub": "study"
}

Public Claim

Public Claim들은 충돌이 방지된 (Collision-Resistant) 이름을 가지고 있어야 한다.

충돌 방지를 위해 Claim 이름을 URI 형식으로 짓는다.

Private Claim

Private ClaimClient-Server 간의 미리 정해져 사용되는 Claim 이름들이다.

Public Claim과 달리 이름이 중복되어 충돌이 될 수 있어 유의해야 한다.


Signature

Signature는 JWT의 무결성을 보증하는데 사용하고,

Private Key로 서명된 토큰의 경우 JWT 발신자가 누구인지 확인할 수도 있다.

Signature를 만들기 위해Encoding된 Header,

Encoding된PayloadSecret Key,

Header에서 지정된 암호화 Algoritm이 있어야 한다.


JWT 과정

1.Browser는 로그인과정에서 회원정보를 Server에 제공.

2.Server는 회원 정보와 Secret Key를 이용, JWT를 생성.

3.Server는 생성한 JWTBrowser에게 전송.

4.Browser는 해당 회원에 대한 정보가 필요할때 발급받은 JWT를 Header에 넣어 Server에게 요청.

5.ServerSecret Key로 요청 JWT의 Signature를 검증한 후 해당 정보를 Browser에게 제공.


JWT 장점

JWT의 장점으로는 수많은 프로그래밍 언어에서 지원되며,

단순 JSON 구조그 자체가 모든 정보를 포함하는 자가수용적(Self-Contained) 특성을 지닌다.
다른 환경과 종속되지 않는 독립적 구조, 만료 기간이 자체 내장

Secret Key를 통해 Server측에서 쉽게 디버깅 및 관리할 수 있고,

수평 스케일링에 용이하다.

또한 HTTP RequestHeader 또는 URL의 Parameter로 쉽게 전송될 수 있다.
REST Service로 제공 가능, 트래픽 부담 저하

사용자 인증에 필요한 모든 정보가 토큰 자체에 포함하기 때문에,

별도의 인증 저장소가 필요없다.

따라서 분산 마이크로 서비스 환경에서,

중앙 집중식 인증 서버데이터베이스의존하지 않는,

쉬운 인증 및 인가 방법을 제공한다.

JWT 단점

JWT는 Client 측에 저장되어 있어, Server DB에서 사용자 정보가 변경되었더라도 Token에 직접 적용할 수 없다.

JWT는 크기가 작지만 만약 Payload의 Claim이 계속 추가되면,
Token이 길어질 수 있다.

이는 Staless Application에서 Token이 항상 Request와 함께 전송되기때문에,
데이터 트래픽 크기에 영향을 끼칠 수 있다.

JWT 사용 해보기

Java에서 jjwt라는 Library로 쉽게 사용해볼 수 있다.

jjwt

jjwtJWT 생성 및 파싱, 검증을 위한 Library이다.

아래 Dependency를 Maven pom.xml에 추가하여 Libarary를 설치해보자.

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

아래 예제 Class 처럼 간단하게 JWT Token을 생성 및 파싱, 검증할 수 있다.
jjwt 0.1x.0 버전대 이후 Deprecated 된 Method들이 많으니 참고만 하자

public class AuthJWT {
    private final String secretKey = "Gil11ogG2200";

    public static void main(String[] args) throws UnsupportedEncodingException {
        AuthJWT authJWT = new AuthJWT();

        String jwt = authJWT.createToken();
        
        Map<String, Object> claimMap = authJWT.verifyJWT(jwt);
        // 토큰 만료 or 검증 실패 시 null
        System.out.println(claimMap); 
    }
        
    public String createToken() {

        //Header 설정
        Map<String, Object> headers = new HashMap<>();
        headers.put("alg", "HS256");
        headers.put("typ", "JWT");

        //payload 설정
        Map<String, Object> payloads = new HashMap<>();
        payloads.put("iss", "gillog");
        payloads.put("aud", "all");
        payloads.put("data", "Gillog JWT");

        Long expiredTime = 1000 * 60L * 60L * 2L; 

        Date expDate = new Date();
        expDate.setTime(expDate.getTime() + expiredTime);
     
        return Jwts.builder()
                .setHeader(headers) // Headers 설정
                .setClaims(payloads) // Claims 설정
                .setSubject("study") // 토큰 용도 
                .setExpiration(expDate) // 토큰 만료 시간 설정
                .signWith(SignatureAlgorithm.HS256, secretKey.getBytes()) // HS256과 Key로 Sign
                .compact(); // 토큰 생성
    }
    
    public Map<String, Object> verifyJWT(String jwt) throws UnsupportedEncodingException {
        Map<String, Object> claimMap = null;
        try {
            Claims claims = Jwts.parserBuilder()
				.setSigningKey(secretKey.getBytes()) // Secreat Key로 Signature 설정
				.build()
				.parseClaimsJws(jwt) // 파싱 실패 시 에러 발생
				.getBody();

            claimMap = claims;

            // Claim 사용 법 일반 Map 형태 처럼 사용
            Date expiration = claims.get("exp", Date.class);
            String data = claims.get("iss", String.class);
            
        } catch (ExpiredJwtException e) { // 토큰 만료
            ...
        } catch (Exception e) { // 그 외 에러
            ...
        }
        return claimMap;
    }    
}
profile
🚀 기록보단 길록을 20.10 ~ 22.02 ⭐ Move To : https://gil-log.github.io/

2개의 댓글

comment-user-thumbnail
2021년 11월 5일

감사합니다~

답글 달기
comment-user-thumbnail
2023년 6월 7일

JWT is defined as a compact and self-contained format using JSON objects to securely transmit information between parties, following the RFC7519 standard.
It provides a means of securely transmitting claims representing the information between parties in a URL-safe compact format. pge outage map

답글 달기