JWT란?

박재언·2023년 5월 13일
0
post-thumbnail

JWT에 대한 이해

JWT란?

JWT(Json Web Token)는 말 그대로 웹에서 사용되는 JSON형식의 토큰에 대한 표준 규격으로 주로 사용자의 인증(authentication) 또는 인가(authorization) 정보를 서버와 클라이언트 간에 안전하게 주고 받기 위해서 사용된다.

  • Authorization(인가): 유저에 대한 권한을 허락하는 것으로 사용자가 로그인하면 이후의 각 요청에서는 JWT가 포함되어 사용자가 해당 토큰으로 허용되는 패스, 서비스 및 리소스에 액세스할 수 있도록 해준다. Single Sign On방식으로 오버헤드가 적고 여러 도메인에서 쉽게 사용할 수 있기 때문에 오늘날 JWT를 널리 사용하는 기능이다.

  • authentication(인증): 사용자가 올바른 사용자임을 확인하면 클라이언트에게 Access Token(JWT)을 발급해준다. 토큰 기반의 인증은 발급해준 후 요청이 들ㅇ오면 검증만 해주면 되기때문에 Stateless하다. 확장성이 뛰어나 토큰 기반의 다른 인증 시스템에 접근이 용이하다.

  • Sngle Sign On(SSO): 하나의 시스템(인증 서버)에서 클라이언트에 대한 인증을 수행하고, 그 인증 정보를 가지고 추가적인 인증 없이 다른 서비스들도 사용할 수 있도록 하는 기능이다. 하나의 인증 정보로 여러 서비스를 사용하기 때문에 여러 서비스에 대한 로그인 처리가 간소해지기 때문에 편리하다는 장점이 있다.


JWT의 구조

JWT는 헤더(header), 정보(payload), 서명(signature) 세 파트로 나눠져 있다. 각 파트는 점(.)으로 구분하며 각 부분은 BASE64로 인코딩 되어 표현된다.

헤더(header)

  • 알고리즘으로 암호화 할 것인지, 어떠한 토큰을 사용할 것 인지에 대한 정보가 들어있다.
  • typ: 토큰의 타입을 지정한다. JWT이다.
  • alg: 해싱 알고리즘 방식을 지정하며, 서명(Signature) 및 토큰 검증에 사용한다.
    • 해싱 알고리즘은 보통 HMAC-SHA256, RSA가 사용된다.

정보(Payload)

  • Payload 부분에는 토큰에 담을 정보가 들어있다. 정보의 한 조각을 클레임(Claim)이라고 부르고 이는 Json(Key, Valye) 형태의 한 쌍으로 이뤄져있다.

  • 토큰에는 여러개의 클레임을 넣을 수 있다.

  • 정보는 수정이 가능하며 더 많은 정보를 추가할수 있지만 노출과 수정이 가능한 지점이기 때문에 인증이 필요한 최소한의 정보만을 담아야한다.

  • 클레임의 종류 3가지

    • 등록된 클레임(Registered Claim)

      • 토큰 정보를 표현하기 위해 이름이 이미 정해진 종류의 데이터다. 등록된 클레임의 사용은 모두 선택적이지만, 사용할 것을 권장한다.
      • iss : 토큰 발급자 (issuer)
      • sub : 토큰 제목 (subject)
      • aud : 토큰 대상자 (audience)
      • exp : 토큰의 만료시간 (expiraton) : NumericDate 형식으로 되어 있어야 하며 현재 시간 이후로 설정되있어야한다.
      • nbf : 토큰 활성 날짜(not before) : NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다.
      • iat : 토큰 발급 시간(issued at) : 토큰 발급 이후의 경과 시간을 알 수 있다.
      • jti : JWT 고유 식별자(JWT ID) : 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용한다.
    • 공개 클레임(Public Claim)

      • 공개 클레임들은 충돌이 방지된 (collision-resistant) 이름을 가져야 하며 충돌을 방지하기 위해서 클레임 이름을 URI 형식으로 짓는다.

      • {"https://velog.io/pju114": true}

  • 비공개 클레임(Private Claim)
    • 비공개 클레임은 사용자 정의 클레임으로, 클라이언트와 서버가 협의하에 임의로 지정한 정보를 저장해서 사용한다.
    • 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할때에 유의해야 한다.
{
 "userId": "dev-coco"
 "username": "coco"
}

서명(Signauture)

  • 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다.
    헤더(Header)와 내용(Payload)의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀키를 이용해 헤더에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64로 인코딩하여 생성한다.
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload), 
secret
)

JWT의 동작원리

http://www.opennaru.com/opennaru-blog/jwt-json-web-token/

  1. 사용자가 id와 password를 입력하여 로그인을 요청
  2. 서버는 회원 DB에 들어가 있는 사용자인지 확인
  3. 서버는 요청을 확인하고 secret key를 통해 Access token을 발급
  4. JWT 토큰을 클라이언트에 전달
  5. 클라이언트에서 API 을 요청할때 클라이언트가 Authorization header에 Access token을 담아서 전송
  6. 서버는 JWT Signature를 체크하고 Payload로부터 사용자 정보를 확인해 데이터를 반환
  7. 클라이언트의 요청에 대한 응답 전달
  • 클라이언트의 로그인 정보를 서버 메모리에 저장하지 않기 때문에 토큰기반 인증 메커니즘을 제공한다.
  • 인증이 필요한 경로에 접근할 때 서버 측은 Authorization 헤더에 유효한 JWT 또는 존재하는지 확인한다.
  • JWT에는 필요한 모든 정보를 토큰에 포함하기 때문에 데이터베이스과 같은 서버와의 커뮤니케이션 오버 헤드를 최소화 할 수 있다.
  • Cross-Origin Resource Sharing (CORS)는 쿠키를 사용하지 않기 때문에 JWT를 채용 한 인증 메커니즘은 두 도메인에서 API를 제공하더라도 문제가 발생하지 않는다.
  • 처음 사용자를 등록할 때 Access token과 Refresh token이 모두 발급되어야 합니다.

JWT의 장점

  • JWT 의 주요한 이점은 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 필요 없다
  • 거의 모든 곳에서 토큰이 생성될 수 있으며, 서버에서 토큰을 확인할 필요가 없다.
  • 쿠키를 전달하지 않아도 되므로 쿠키를 사용함으로써 발생하는 취약점이 사라진다.
  • 분산 마이크로 서비스 환경에서 중앙 집중식 인증 서버와 데이터베이스에 의존하지 않는 쉬운 인증 및 인가 방법을 제공한다.
  • 내장된 기능으로 액세스 가능한 데이터, 권한 지속 시간, 로그인 시 가능한 작업을 지정할 수 있다.
  • JSON 코드 언어로 생성된 토큰은 용량이 작기 때문에 트래픽 대한 부담이 낮다.
  • REST 서비스로 제공 가능하다.

JWT의 단점

  • 토큰은 클라이언트에 저장되어 데이터베이스에서 사용자 정보를 조작하더라도 토큰에 직접 적용할 수 없다.
  • 단일 키를 이용 함으로 키가 유출되면 시스템 전체가 위험에 노출된다.
  • 토큰은 이해하기가 쉽지 않아 개발자가 암호 서명 알고리즘에 잘 모른다면 자신도 모르게 시스템을 위험에 빠뜨릴 수 있다.
  • 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능하다
  • 토큰을 탈취당하면 대처하기 어렵고, 특정 토큰을 강제 만료하기 어렵다.
  • Payload 자체는 암호화되지 않기 때문에 중요한 정보를 담을 수 없다.
  • 토큰의 페이로드(Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.

0개의 댓글