JWT(Json Web Token)

Wonjun Seo·2024년 2월 23일
0

JWT

JWT(JSON Web Token)은 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 말한다. 그리고 JWT 기반 인증은 JWT를 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식이다.

JWT는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이며, 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명도 들어있다. 따라서 사용자가 JWT를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려준다.


JWT 프로세스

로그인 전(JWT를 발급받기 전)의 과정:

  1. 사용자가 아이디와 비밀번호를 이용하여 서버에 로그인 요청을 보낸다.
  2. 서버는 비밀키를 사용해 JSON 객체를 암호화한 JWT를 발급한다.
  3. JWT를 헤더에 담아 클라이언트에게 보낸다.

로그인 후(JWT를 발급받은 후)의 과정:

  1. 클라이언트는 JWT를 로컬(LocalStorage, Cookie)등에 저장한다.
  2. API를 호출할 때마다 매번 JWT를 헤더에 실어서 보낸다.
  3. 서버는 헤더를 매번 확인하여 JWT가 유효한지를 확인하고, 인증이 되면 API에 대한 응답을 보낸다.

JWT 구조

JWT는 각각의 구성요소가 점(.)으로 구분되어 있다. JWT는 Header, Payload, Signature로 구성되어 있다.


{
	"typ": "JWT",
    "alg": "HS512"
}
  • alg: Signature에서 사용하는 알고리즘
  • typ: 토큰 타입

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

Signature에서 사용하는 알고리즘은 대표적으로 RS256HS512등이 있다.

위의 경우에는 현재 토큰의 타입이 JWT이고, 개인키로 HS512 알고리즘이 적용되어 암호화가 되었다고 확인할 수 있다.

Payload

{
  	"user_id": "abc",
  	"iat": 1708647264,
  	"exp": 1708733664,
  	"iss": "test",
  	"sub": "access_token"
}

Payload에는 보통 Claim이라는 사용자 또는 토큰에 대한 property를 key-value 형태로 저장한다.

표준 스펙상 key의 이름은 3글자로 되어있다.

  1. iss (Issuer): 토큰 발급자
  2. sub (Subject): 토큰 제목 -> 토큰에서 사용자에 대한 식별 값
  3. aud (Audience): 토큰 대상자
  4. exp (Expiration Time): 토큰 만료 시간
  5. nbf (Not Before): 토큰 활성 날짜
  6. iat (Issued At): 토큰 발급 시간
  7. jti (JWT ID): JWT 토큰 식별자 (Issuer가 여러 명일 때 이를 구분하기 위한 값)

Signature

Signature는 헤더와 페이로드의 문자열을 합친 후에 헤더에서 선언한 알고리즘과 key를 사용해 암호화 한 값이다.

Header와 Payload는 단순히 Base64url로 인코딩되어 있어 누구나 쉽게 복호화할 수 있지만, Signature는 key가 없으면 복호화할 수 없다.

Header에서 선언한 알고리즘에 따라 key는 개인키가 될 수도 있고, 비밀키가 될 수도 있다. 개인키로 서명했다면 공개키로 유효성 검사를 할 수 있고, 비밀키로 서명했다면 비밀키를 가지고 있는 사람만이 유효성 검사를 할 수 있다.

https://jwt.io/ 에 직접 들어가 token 값을 입력하면 현재 자신이 사용중인 토큰이 어떤 구조로 되어있는지 쉽게 확인할 수 있다. exp와 iat의 경우 Datetime에 마우스를 갖다대면 정확한 날짜와 시간을 볼 수 있다.

이렇듯 Header와 Payload는 누구나 쉽게 확인할 수 있기 때문에 이 부분들에는 중요한 정보를 담으면 안된다.


JWT 장단점

장점

  • Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다.
  • 인증 정보에 대한 별도의 저장소가 필요없다.
  • 공개키(개인키)를 통해 서명되기 때문에 안전하다.
  • 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다.
  • 모바일 애플리케이션 환경에서도 잘 동작한다.

단점

  • 토큰의 크기가 커질수록 트래픽에 영향을 미칠 수 있다.
  • 토큰은 클라이언트 측에서 관리되어 토큰이 탈취당하면 대처하기가 어렵다.
  • Payload 자체는 암호화 된 것이 아니라 BASE64로 인코딩 된 것이기 때문에 중간에 Payload를 탈취당하면 데이터를 볼 수 있으므로 중요 데이터를 넣지 않아야 한다.

참고자료

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC

https://velog.io/@chuu1019/%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90-JWTJson-Web-Token

0개의 댓글