JWT(Json Web Token)

허준기·2024년 2월 13일
0

스프링

목록 보기
7/7

JWT(Json Web Token)

정보를 비밀리에 전달하거나 인증할 때 주로 사용하는 토큰
Json 객체를 이용
쿠키와 달리 클라이언트에 많은 양의 정보를 담지 않음
세션과 달리 서버에서 상태를 유지하지 않음
stateless

JWT의 구성

JWT는 3개의 문자열로 구성되어 있다

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJuYW1lIjoi7ZeI7KSA6riwIn0
.KQcvhAOTFvw1VNcBdijI5Z7BEdr4ozyXrrlrmXkizO0

이건 예시로 가져온 JWT이다
중간에 .이 2개 보이는데 이걸로 구분이 된다

맨 앞의 문자열은 Header이다

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

이런식으로 구성된 정보가 들어간다.
type은 우리가 사용하는 것이 JWT이므로 JWT가 들어가야 된다

alg는 알고리즘을 뜻하는데 signature 부분의 값을 만드는데 사용될 알고리즘을 정해준다
여기서는 HS256이라는 알고리즘을 지정해준 것을 볼 수 있다

Payload

두 번째 문자열은 Payload(정보)이다

//.eyJuYW1lIjoi7ZeI7KSA6riwIn0
{
  "name": "허준기"
}

이런식으로 json 형식으로 여러 정보들이 담겨있다

지금은 내 이름밖에 넣어놓지 않았는데 다른 정보들도 더 넣을 수 있다

Signature

Header의 인코딩 값과 Payload의 인코딩 값을 합친 후, secret key해쉬를 해 생성한다

//.KQcvhAOTFvw1VNcBdijI5Z7BEdr4ozyXrrlrmXkizO0

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  "secret key"
)

이런식으로 구성되어 있다
저기에 secret key라고 해놨는데 내가 해놓은 secret key는 저게 아니다!
비밀이니까 안보여준다.

아무튼 secret key를 이용해서 토큰을 만들어준다

위에 한것처럼 토큰을 만들어보고 싶다면
https://jwt.io/
여기서 해보면 된다

JWT 발행

이제 구조를 알아봤으니 사용을 해보자
나는 자바에서 사용을 했다


public String createToken(Integer schoolId) {

        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        return Jwts.builder()
                .expiration(Date.valueOf(LocalDateTime.now().plusMinutes(expiredTime).toLocalDate()))
                .claim("schoolId", schoolId)
                .signWith(key)
                .compact();
    }
    

이 메서드를 통해서 JWT를 발행해줬다
이 때 expiredTime이랑 secretKey는 위에서 미리 선언을 해놓은 것이다

이 메서드는 학번만 인자로 전달해서 JWT를 발행한다

현재시간에 expiredTime을 더해서 유효기간을 정해준다

JWT 추출

이제 반대로 JWT에서 원하는 값을 뽑아와보자

public Integer getSchoolId(String token) {

        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        String schoolId = Jwts.parser()
                .verifyWith(key)
                .build()
                .parseSignedClaims(token)
                .getPayload()
                .get("schoolId").toString();

        return Integer.parseInt(schoolId);
    }

이렇게 JWT에서 schoolId를 뽑아올 수 있다
나는 이 메서드로 존재하는 사용자인지 비교를 해줬다

지금까지 사용방법을 알아봤고 이제 주의점에 대해서 알아보자

주의점

alg : none 공격

위에서 말한대로 Header 부분에 알고리즘을 지정해줄 수 있다.
이 때 공격자가 alg 부분에 none이라고 넣어서 요청을 보내면 뚫리는 경우가 있다고 한다
→ 최신 라이브러리들을 잘 쓰면 된다고 한다

JWT는 변환이 쉬움

JWT디코딩이 굉장히 쉽기 때문에 민감한 정보를 넣어서 저장하면 안된다
→ 꼭 필요한 정보들만 넣어서 전달하자(민감한 정보 말고)

Secret Key 문제

secretKey를 설정해줄 때 간단하고 유추 가능한 문자열로 적을 경우 때려 맞힐 가능성이 있으니 주의해라

  • 키를 매우 길게 설정
  • 공유 금지
  • 생성용키/검증용키 2개 사용

JWT 탈취

누가 JWT를 탈취할 경우가 생길 수도 있다
하지만 JWT는 사용 정지가 불가능하다
그래서 해당 JWT의 유효기간이 지나기 전까지 탈취자는 마음대로 입장을 할 수 있다

  • 블랙리스트 사용 &rarr JWT를 사용하는 의미가 없어짐
  • 유효기간 짧게 유지
  • 훔치기 어렵게 만들기 → HttpOnly cookie
  • refresh token rotation → 1회용

참고

코딩애플
JWT란 무엇인가

profile
나는 허준기

0개의 댓글