WEB | JWT란 무엇일까?

바다·2024년 5월 21일
0

WEB

목록 보기
11/12
post-thumbnail

JWT란 무엇일까?

JWT(Json Web Token)

특징

  • 인터넷 표준 인증 방식

  • 인증에 필요한 정보들을 Token에 담아 암호화 시켜 사용하는 것

  • 일반적으로 쿠키 저장소를 사용하여 JWT를 저장한다

  • 필요한 모든 정보를 한 객체에 담아서 전달하기 때문에 JWT 한 가지로 인증을 마칠 수 있다

  • JWT는 서명된 토큰

  • 공개/개인 키를 쌍으로 사용하여 토큰에 서명할 경우 서명된 토큰은 개인 키를 보유한 서버가 서명된 토큰이 정상적인 토큰인지 인증할 수 있다

  • JWT의 구조 때문에 인증 정보를 담아 안전하게 인증을 시도하게끔 전달할 수 있다

공식 사이트 : https://jwt.io/


JWT를 언제 사용하나요?

승인

JWT를 사용하는 가장 일반적인 경우
사용자가 로그인을 하면 각 후속 요청에 JWT가 포함되어 사용자가 해당 토큰으로 허용되는 경로, 서비스 및 리소스에 엑세스 할 수 있다

정보 교환

JWT는 당사자 간에 정보를 안전하게 전송할 수 있는 방법 중 하나

  • 공개/개인 키 쌍을 사용하여 JWT에 서명할 수 있으므로 보낸 사람이 누구인지 확인할 수 있다
  • Header와 Payload를 사용해 서명을 계산하므로 콘텐츠가 변조되지 않았는지 확인할 수 있다

JWT를 왜 사용하나요?

-Session 로그인 기능을 사용할 경우, Session storage가 모든 Client의 로그인 정보를 소유하고 있기 때문에 모든 서버에서 Session storage를 방문하여 API 요청을 처리해야 한다.
하지만, JWT를 사용한다면 로그인 정보를 Server에 저장하지 않고 Client에 로그인 정보를 JWT로 암호화하여 저장하기 때문에 JWT를 통해 인증과 인가 과정을 진행시킬 수 있다
모든 서버에서는 동일한 Secret Key를 소유하고, 이 Secret Key를 통해 암호화와 위조 검증이 가능하다

(Secret Key)에 대한 내용은 나중에 더 다루어볼 생각이다

장점

  1. 동시 접속자가 많을 때 서버 측의 부하를 낮춘다
  2. Client, Server가 다른 도메인을 사용할 때 유용하다

단점

  1. 구현의 복잡도가 증가한다
  2. JWT에 담는 내용이 커질 수록 네트워크 비용이 증가한다
  3. 이미 생성된 JWT를 일부만 만료시킬 방법이 없다
  4. Secret Key가 유출된다면, JWT를 조작할 수 있다

JWT의 구조

HEADER . PAYLOAD . SIGNATURE

위와 같이 헤더, 내용, 서명이 .(dot)을 구분자로 하여 JWT 토큰 1개를 이룬다

완성된 토큰은 다음과 같은 형태를 가진다

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1. Header

ALGORITHM & TOKEN TYPE

Header에는 보통 토큰의 타입과, 서명을 생성할 때 어떤 알고리즘이 사용되었는지 저장한다

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

위와 같은 경우는, 현재의 토큰 타입이 JWT이고, 서명을 생성할 때 HS256 알고리즘이 적용되어 암호화가 되어 있음을 나타낸다

2. Payload

DATA

Payload에는 Claim을 포함한다. 클레임은 Entity(일반적으로 사용자) 및 추가 데이터에 대한 설명이다. 클레임에는 등록된 클레임, 공개 클레임, 비공개 클레임 세 가지의 유형이 있다.

등록된 클레임(Registered Claim)

유용하고 상호 운용 가능한 클레임 집합을 제공하기 위해 필수는 아니지만 권장되는 미리 정의된 클레임 집합이다.
그 중에는 iss (발행자), exp (만료 시간), sub (토큰 제목), aud (토큰 대상자) 등이 있다.

표준 스펙 상 key의 이름은 3글자로 되어 있다.
JWT의 핵심 목표는 사용자에 대한, 토큰에 대한 표현을 압축하는 것이기 때문에 이를 정의한 것이라고 볼 수 있다.

공개된 클레임(Public Claim)

JWT를 사용하는 사람들이 원하는 대로 정의할 수 있다.
그러나 충돌을 방지하려면 IANA JSON 웹 토큰 레지스트리에 정의하거나 충돌 방지 네임 스페이스를 포함하는 URI로 정의해야 한다

비공개 클레임(Private Claim)

사용에 동의한 당사자 간에 정보를 공유하기 위해 생성된 맞춤 클레임으로, 등록되거나 공개된 클레임이 아니다

Payload의 예시

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

위 Payload에서는 토큰의 제목과 대상자의 이름, 그리고 토큰 발급 시간을 나타낸다

가장 중요한 점

Payload에 민감한 정보를 담지 않는 것!

header와 payload는 json이 인코딩 되어 있을 뿐, 특별한 암호화가 걸려 있는 것이 아니기 때문에 누구나 jwt를 가지고 디코딩을 하면 그 값을 알 수 있다

JWT는 단순하게 "식별을 하기 위한" 정보만을 담아두어야 한다

3. Signature

VERIFY SIGNATURE

가장 중요한 서명!

서명 부분을 생성하려면 인코딩된 헤더, 인코딩된 페이로드, secret key, 헤더에 지정된 알고리즘 을 가져와서 서명해야 한다

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  [your-256-bit-secret]
)

위는 HMAC SHA256 알고리즘을 사용해서 서명을 생성하려는 경우이다

서명은 메시지가 도중에 변경되지 않았는지 확인하는 데 사용되며, 개인 키로 서명된 토큰의 경우 JWT를 보낸 사람이 누구인지도 확인할 수 있다


JWT는 어떻게 작동하나요?

  • 인증 시 사용자가 자격 증명을 사용하여 성공적으로 로그인하면 JSON 웹 토큰이 반환된다
  • 사용자가 보호된 경로나 리소스에 엑세스하려고 할 때마다 사용자 에이전트는 일반적으로 Bearer 스키마를 사용하여 Authorization 헤더에 JWT를 보내야 한다
    Authorization : Bearer <Token>
  • 서버의 보호된 경로는 헤더에서 유효한 JWT를 확인하고 Authorization, JWT가 있으면 사용자는 보호된 리소스에 엑세스할 수 있다

다음 다이어그램은 API 또는 리소스에 엑세스하기 위해 JWT를 획득하고 사용하는 방법을 보여 준다

1. 애플리케이션이나 클라이언트가 인증 서버에 인증을 요청
2. 권한이 부여되면 권한 서버는 애플리케이션에 엑세스 토큰을 반환
3. 애플리케이션은 엑세스 토큰을 사용하여 보호된 리소스(예 : API)에 엑세스

주의할 점

  • HTTP 헤더를 통해 JWT 토큰을 보내는 경우 토큰이 너무 커지지 않도록 해야 한다

  • 토큰이 Authorization 헤더로 전송되면 CORS(Cross-Origin Resource Sharing)는 쿠키를 사용하지 않으므로 문제가 되지 않는다

profile
ᴘʜɪʟɪᴘᴘɪᴀɴs 3:14

0개의 댓글