[F-Lab 모각코 챌린지 27일차] JWT Jason Web Token

Nami·2023년 6월 27일
0

66일 포스팅 챌린지

목록 보기
27/66

JWT Jason Web Token

JWT는 인증된 사용자 정보를 전송하기 위한 토큰 기반 인증 방식이다.

  • JWT는 JSON 형식으로 구성되며, 사용자의 클레임(Claim)정보와 전자 서명(Signature)을 포함하고 있다.
  • 말그대로 웹에서 사용되는 JSON 형식의 토큰에 대한 표준 규격.
  • 주로 사용자의 인증(athentication) 또는 인가(athorization) 정보를 서버와 클랑이언트 간에 안전하게 주고 받기 위해 사용된다.
  • 서명된 토큰은 클레임의 무결성을 확인할 수 있고, 암호화된 토큰은 다른 당사자로부터 해당 클레임을 숨긴다.
  • 공개/개인 키 쌍을 사용해서 토큰에 서명할 때 서명은 개인 키를 보유한 당사자만이 서명한 당사자임을 인증한다.

JWT 구조

하나의 JWT 토큰은 헤더(header)페이로드(payroad), 서명(signature). 이렇게 세 부분으로 이루어지며 각 구역이 , 기호로 구분된다.

<헤더>,<페이로드>,<서명>
xxxxx.yyyyy.zzzzz
  1. 헤더
    토큰의 유형과 서명 알고리즘이 명시된다.
  2. 페이로드
    Claim이라 불리는 사용자의 인증/인가 정보가 담긴다.
  3. 서명
    헤더와 페이로드가 비밀키로 서명되어 저장된다.

토큰은 네트워크로 전송되어야 하기 때문에 공간을 적게 차지하는 것이 유리하다. JSON 형식으로 데이터를 저장할 때 키(key)를 3글자로 줄이는 관행이 있다.

// 헤더
{
  "alg": "HS256",
  "typ": "JWT"
}
// 페이로드
{
  "sub": "1234567890",
  "lat": 1516239022
}

JWT에서 자주 사용되는 JSON 키 이름은 다음과 같다.

  • sub 키: 인증 주체(subject)
  • iss 키: 토큰 발급처
  • typ 키: 토큰의 유형(type)
  • alg 키: 서명 알고리즘(algorithm)
  • iat 키: 발급 시각(issued at)
  • exp 키: 말료 시작(expiration time)
  • aud 키: 클라이언트(audience)

JWT를 통한 인증과 인가

보통 실무에서 OAuth나 OIDC 프로토콜과 함께 인증이나 인가를 위해 주 사용이된다.
클라이언트가 어떤 서비스의 인가 서버를 통해 로그인에 성공하면 JWT 토큰을 획득할 수 있다. 클라이언트는 해당 서비스의 API를 호출할 때 JWT 토큰을 보내서 원하는 자원에 접근하거나 허용된 작업을 수행할 수 있게 된다.

인증에서 사용자가 자격 증명을 사용허여 성공적으로 로그인하면 JSON 웹 토큰이 반환된다. 토큰은 자격 증명이므로 보안 문제를 방지하기 위해 세심한 주의를 기울여야 한다. 일반적으로 필요 이상으로 토큰을 보관해서는 안됨.
일부 서버에는 헤더에 8KB 이상을 허용하지 않음.

민감한 세션 데이터를 브라우저 저장소에 저장해서는 안된다.

사용자가 보호된 경로 또는 리소스에 엑세스하려고 할 때 마다 사용자 에이전트는 일반적으로 Bearer 스키마를 사용하여 Authorization 헤더에서 JWT를 보내야한다.

Authorization: Bearer <token>

기존의 토큰 방식 인증은 다음과 같은 과정으로 작동한다:

  1. 클라이언트가 인증을 위해 자격 증명(예: 사용자 이름과 비밀번호)을 서버에 제공.
  2. 서버는 클라이언트의 자격 증명을 확인하고, 유효한 경우에는 클라이언트에게 액세스 토큰을 발급.
  3. 클라이언트는 이후의 모든 서비스 호출에 액세스 토큰을 포함하여 서버에 요청
  4. 서버는 클라이언트로부터 받은 액세스 토큰을 확인하여 유효성을 검증.
  5. 액세스 토큰이 유효하다면, 서버는 클라이언트의 요청에 대한 서비스를 제공하고 필요한 세부 정보를 반환.
  6. 클라이언트는 세부 정보를 받아 처리하고, 추가적인 서비스를 위해 필요한 경우 다시 서버에 요청.

이런 방식에서 참조에 의한 호출(By Reference)형태는 엑세스 토큰이 실 서버에서 세부 정보를 조회할 수 있는 토큰 참조값을 가지고 있음을 의미한다. 클라이언트가 서비스를 받기 위해서는 매 요청마다 액세스 토큰을 사용하여 서버에 접속, 서버는 액세스 토큰의 유효성을 확인한 후 세부 정보를 쿼리하여 응답한다.

이 방식은 각 서비스 요청마다 액세스 토큰을 사용해야해서 성능 면에서 일부 지연이 발생할 수 있다.

JWT와 같이 값에 의한 호출(By Value) 형태가 가능한 토큰이 필요하다.
토큰이 필요한 모든 정보를 클라이언트가 갖고 있어 서버 연결이 필요없기 때문에 마이크로서비스 자체에서 유효성을 검증한다.

장점

JWT가 등장하기 전에는 웹에서 쿠키와 세션을 이용한 사용자 인증을 구현하는 경우가 많았다.
JWT는 토큰 자체에 사용자의 정보가 저장되어 있기 때문에 서버 입장에서 토큰을 검증만 해주면 됨.
별도의 인증 저장소가 필요없다는 것. 이는 분산 마이크로 서비스 환경에서 중앙 집중식 인증 서버와 데이터베이스에 의존하지 않는 쉬운 인증 및 인가 방법을 제공함.
반면 쿠키와 세션은 서버 단에 로그인한 모든 사용자의 세션을 DB나 캐시에 저장해놓고 쿠키로 넘어온 세션 ID로 데이터를 매번 조회해야함.
JWT를 사용할 땐 사용자가 늘더라도 사용자 인증을 위해 추가로 투자해야하는 인프라 비용을 크게 절감 가능.
쿠키 사용이 없으므로 CORS(Cross-Origin Resource Sharing)문제에서도 자유로워짐.

1. 자가수용(Self-contained): JWT는 필요한 사용자 정보를 토큰 자체에 포함하고 있기 때문에, 서버에 상태 정보를 저장하거나 토큰을 DB에서 조회할 필요가 없다. 이는 서버의 확장성과 성능을 향상시킬 수 있.

2. 확장성: JWT는 분산 시스템 및 마이크로서비스 아키텍처에 적합. 각 서비스는 토큰을 검증하는 키만을 갖고 있으면 되므로, 서비스 간의 독립성과 확장성이 높아진다.

3. 보안: JWT는 서명 또는 암호화를 통해 토큰의 무결성과 기밀성을 보장할 수 있다. 서명된 토큰은 위조나 변경이 불가능하며, 암호화된 토큰은 제3자로부터 보호됨.

4. 다양한 플랫폼 지원: JWT는 JSON 형식을 사용하므로, 다양한 프로그래밍 언어와 플랫폼에서 사용이 가능. 이는 시스템 간의 통합과 상호 운용성을 간소화.

단점

1. 크기: JWT는 정보를 포함하고 있기 때문에, 토큰의 크기가 상대적으로 크다는 단점이 있다. 특히, 클레임의 수가 많거나 추가 데이터를 포함해야 할 경우 더 큰 토큰이 생성될 수 있다.

2. 캐싱의 어려움: JWT는 자체적으로 상태를 갖지 않기 때문에, 토큰을 취소하거나 갱신하는 것이 어렵다. 만료 시간을 설정하여 일정 시간이 지나면 토큰이 만료되도록 관리해야 한다.

3. 중요한 정보의 노출 위험: JWT는 토큰 자체에 클레임 정보를 포함하기 때문에, 중요한 정보(예: 비밀번호)를 포함하지 않도록 주의해야 함. 필요한 경우에는 클레임에 대한 최소한의 정보만 포함한다.

4. 토큰 관리의 어려움: JWT는 토큰을 발급한 이후에는 수정할 수 없기 때문에, 토큰을 주기적으로 갱신하거나 취소하기 어렵다. 토큰의 유효기간을 적절히 설정하고, 필요한 경우에는 토큰 재발급을 고려해야 함.

즉, JWT를 사용할 때에는 보안 요구사항, 시스템 아키텍처, 데이터 크기 등을 고려해야 함.

프로젝트에 쓰이는 경우가 많다고 해서 추후에 실제로 구현해보려한다!


참조 ✅

0개의 댓글