Web/Theory

JWT (JSON Web Token)

Alioth02 2024. 5. 8. 01:53

0. JWT?

자바스크립트의 Object 자료구조(Key:Value)를 가지고 있으며,

Web Token으로써 로그인과 같은 기능에서 클라이언트의 인증에 사용된다.

1. JWT 구조

// 헤더.내용.서명
base64(HEADER).base64(PAYLOAD).base64(SIGNATURE)

ex) 헤더.내용.서명

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJuYW1lIjoiQWxpb3RoIiwidXNlcmlkIjoiYWRtaW4ifQ.Ebh4YMPYk7-TiWv20XsbbnEplABvVDvac0ATbDXCcpo

1.1. Header 헤더

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

// HMAC SHA 256 사용
// JWT 지정

사용된 해시 알고리즘(HS256), 토큰 타입(JWT)를 명시한다.

헤더 : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

1.2. Payload 내용

payload의 내용은 단순히 base64 암호화된 부분이기 때문에 (누구나 디코딩 가능)

비밀번호와 같은 중요 정보가 담겨서는 안된다.

{
  "sub": "1234567890",
  "iat": 1516239022,
  "name": "Alioth",
  "userid": "admin"
}

페이로드 : eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJuYW1lIjoiQWxpb3RoIiwidXNlcmlkIjoiYWRtaW4ifQ

1.2.1. Registered Claim (등록된 클레임)

토큰에 대한 정보를 나타내기 위해

이미 등록돼 있는 클레임

iss : 토큰 발급자 (issuer)
sub : 토큰 제목 (subject)
aud : 토큰 대상자 (audience)
exp : 토큰의 만료시간 (expiraton) // NumericDate 형식 ex) 1480849147370
nbf : 토큰의 활성 날짜 (not before) // 지정된 날짜가 지나기 전까지 토큰이 처리되지 않음
iat : 토큰이 발급된 시간 (issued at)

// 이외의 Registered Claim
https://datatracker.ietf.org/doc/html/rfc7519#section-4.1

1.2.2. public claim (공개 클레임)

사용자가 자유롭게 작성 가능하지만,

충돌 방지된 이름을 가지고 있어야 한다.

IANA JSON 웹 토큰 레지스트리 : https://www.iana.org/assignments/jwt/jwt.xhtml

충돌 방지를 위해

IANA JSON 웹 토큰 레지스트리에 정의돼 있는 클레임을 사용하거나, 

{
    "https://고유한_URI/고유한_네임스페이스/추가_경로": true,
    "https://velvetviolet1024.tistory.com/jwt_payload/public_claim": true
}

클레임 이름을 위와 같이 URI 형식으로 사용해야 한다.

1.2.3. private claim (비공개 클레임)

클라이언트와 서버 간에 합의하에 사용되는 클레임

{
    "userid": "admin",
    "username": "alioth"
}

1.3. Signature 서명

헤더 혹은 페이로드의 변조를 체크하는 값

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret_key!
)

헤더와 페이로드의 base64 인코딩값을 합친 후,

주어진 비밀키로 전체를 해쉬화 하여 서명한다.

서명 : Ebh4YMPYk7-TiWv20XsbbnEplABvVDvac0ATbDXCcpo

1.4. JWT 생성

JWT : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJuYW1lIjoiQWxpb3RoIiwidXNlcmlkIjoiYWRtaW4ifQ.Ebh4YMPYk7-TiWv20XsbbnEplABvVDvac0ATbDXCcpo

앞에서 만든 헤더와 페이로드, 서명 값을

"."(dot)를 구분으로 연결해주면 JWT 값이 완성된다.

해당 값을 jwt Debugger(https://jwt.io/)에 넣어보면 헤더와 페이로드가 잘 나오는 것을 확인할 수 있다.

2. JWT 작동 원리

JWT 시스템에서 클라이언트가 로그인을 하면, 서버는 클라이언트의 정보에 기반한 토큰을 발급하여 전달해준다.

그리고 클라이언트가 서버에 요청을 할 때 마다 JWT를 포함해서 전달한다.

서버는 클라이언트에 요청을 받을 때 마다, 

토큰유효(만료)한지, 서명(secret_key)을 통해 내용이 변조되진 않았는지 검증 후, 요청에 응답한다.

서버 측에서는 클라이언트의 세션을 유지할 필요가 없고,

클라이언트의 요청 시, 토큰만 확인하면 되기 때문에 서버 자원을 아낄 수 있다.

Access Token : 서버 API(엑세스)를 요청할 때 사용
Refresh Token : 엑세스 토큰 만료 시, 재발급 목적으로 사용

JWT 토큰은 위의 두 토큰으로 나뉘어 관리된다.

때문에 토큰의 만료시간이 지나도, 서버가 리프레시 토큰의 유효성을 검사하여

클라이언트가 요청한 응답과 함께 엑세스 토큰을 재발급한다.

3. JWT 탈취 방지 방안

3.1. HTTP Only Cookie

JWT 값도 쿠키 값에 들어가기 때문에

쿠키 설정 시, HttpOnly 옵션을 설정하면 XSS 공격을 방지할 수 있다.

// 클라이언트에서 JavaScript의 Document.cookie API 접근 불가능

 

3.2. CORS(Cross-Origin Resource Sharing) // 교차 출처 리소스 공유

지정한 프로토콜(ex : https), 도메인(ex : google.com), 포트(ex : 443)가 전부 같은 환경에서만

토큰을 허용할 수 있도록 도메인을 제한할 수 있다.

// 다른 도메인에서 우리 도메인의 쿠키 접근 불가능

3.3. etc ..

3.3.1. 토큰의 만료시간 짧게 설정 하기

3.3.2. 프레시 토큰은 일회용으로 사용하기 (Refresh Token Rotation) // 리프레시 토큰 탈취를 방지하기 위함

3.3.3. 헤더에 해시 알고리즘 꼭 기입하기

3.3.4. secret_key 어렵게 설정하기 // Brute Force Attack 대비

4. References

https://developers.worksmobile.com/kr/docs/auth-jwt

 

NAVER WORKS Developers

 

developers.worksmobile.com

https://velopert.com/2389

 

[JWT] JSON Web Token 소개 및 구조 | VELOPERT.LOG

지난 포스트에서는 토큰 기반 인증 시스템의 기본적인 개념에 대하여 알아보았습니다. 이 포스트를 읽기 전에, 토큰 기반 인증 시스템에 대해서 잘 모르시는 분들은 지난 포스트를 꼭 읽어주세

velopert.com

https://velog.io/@vamos_eon/JWT%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80-1

 

JWT란 무엇인가? 그리고 어떻게 사용하는가? (1) - 개념

안녕하세요, 주니어 개발자 Eon입니다.오늘 다룰 내용은 JWT (Json Web Token)입니다.사용하는 / 사용되는 로직은 다음 포스트에서 다루겠습니다.토큰 관련된 인증은 대부분 로그인할 때 사용됩니다.

velog.io

https://puleugo.tistory.com/138

 

우리는 왜 JWT를 사용하는가? / JWT 사용 이유

서론 CS 스터디를 준비하다가 웹 보안에 대한 주제로 스터디를 진행하기로 하였다. 그 중 JWT에 대한 내용을 조사하다가 고민해본 점을 정리한다. What is JWT JSON Web Token의 준말입니다. 자바스크립

puleugo.tistory.com

https://velog.io/@vamos_eon/JWT%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80-%EC%82%AC%EC%9A%A9%EC%B2%982

 

JWT란 무엇인가? 그리고 어떻게 사용하는가? (2) - 사용처

안녕하세요, 주니어 개발자 Eon입니다. 이번 글에서 다룰 내용은 JWT가 사용되는 순서입니다. JSON Web Token 인증 수단입니다. 토큰으로 해당 요청이 유효한지 확인할 수가 있습니다. 일반적인 간단

velog.io

https://velog.io/@vamos_eon/JWT%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80-%EB%B3%B4%EC%95%883

 

JWT란 무엇인가? 그리고 어떻게 사용하는가? (3) - 보안

안녕하세요, 주니어 개발자 Eon입니다. 이번 포스트에서는 JWT를 활용한 환경에서의 보안에 대해 다루겠습니다. 보안은 신중에 신중을 기해야 하는 부분입니다. 너무 과하면 서비스에 부담을 주

velog.io