[WEB] JWT 토큰 인증의 개념과 장단점

1. JWT의 개념

JWT는 웹에서 사용자 인증/인가에 사용하는 토큰으로 Json Web Token의 줄임말이다. 웹에서 사용되는 JSON 형태의 토큰 표준 규격이며 쿠키와 유사하지만, 서명된 토큰이라는 차이점이 있다. 공개키, 개인키의 쌍으로 사용할 경우 서명된 토큰은 개인키를 보유한 서버에서만 복호화가 가능하다.

 

보통 Authorization HTTP 헤더를 Bearer <토큰> 형태로 설정하여 클라이언트에서 서버로 전송한다. 서버에서는 토큰에 포함되어 있는 서명정보로 위변조를 검증하며 토큰은 Base64 인코딩 되어있다.

 

2. JWT 구조

header, payload, signature가 각각 . 으로 구분되어 있다

<header>.<payload>.<signature>
  • header - 토큰의 타입, 서명 알고리즘 이 저장
{
  "alg": "HS256",
  "typ": "JWT"
}

 

  • payload - 사용자의 인증 / 인가 정보를 key-value 형태로 저장
{
  "sub": "1234567890",
  "name": "Ado Kukic",
  "admin": true,
  "iat": 1464297885
}
  • signature - header와 payload가 비밀키로 서명되어 저장, header를 디코딩한 값, payload를 디코딩한 값을 합치고 서버의 개인키로 암호화를 한 값

3. JWT 표준 스펙

payload의 key의 값은 자유롭게 설정이 가능하지만, 네트워크 상으로 전송되기에 크기가 작아야 유리하기에 JSON 형태로 데이터를 저장할 때 키를 3글자로 줄이는 관행이 있다. 다음은 JWT key의 표준 스펙이다.

  • sub(subject) - 인증주체
  • iss(issue) - 토큰 발급처 
  • typ(type) - 토큰유형
  • alg(algorithm) - 서명 알고리즘 
  • iat(issued at) - 발급 시각 
  • exp(expiration time) - 만료 시각 
  • aud(audience) - 클라이언트 
  • jti(JWT Id) - JWT 토큰 식별자, iss가 여러 명일 때 구분하기 위한 값

4. JWT를 통한 인증

출처:&nbsp;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

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

 

5. 장점

  • 토큰 검증만을 통해 사용자 정보를 확인가능 하여 추가 검증 로직이 필요 없다.
  • 매번 세션이나 데이터베이스 같은 인증 저장소가 필요 없다.
  • 사용자가 늘어나더라도 사용자 인증을 위한 추가 리소스 비용이 없다.
  • 다른 서비스에 공통 스펙으로 사용이 가능하여 확장성이 높다.

6. 한계

  • base64 인코딩 정보를 전달하기에 전달량이 많다.
  • 토큰이 탈취당할 시 만료될 때까지 대처가 불가능하다.
  • Payload부분은 누구든 디코딩하여 확인할 수 있다.

위의 세 가지 예시로 JWT 토큰을 생성하면 다음과 같다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkbyBLdWtpYyIsImFkbWluIjp0cnVlLCJpYXQiOjE0NjQyOTc4ODV9.XRt6GrUEcSJiGRIU0jScszrjunhot3l75g6x8ZCbpV0

토큰 자체는 암호화되어있지 않기에 jwt.io 등을 통해 디코딩할 경우 데이터를 바로 확인이 가능하다.

7. 주의사항

  • JWT토큰은 누구나 열람이 가능하기에 민감한 사용자 정보를 토큰에 그대로 저장하면 안 된다.
  • 토큰에는 사용자를 식별할 수 있는 ID정도만 저장해야 하며 꼭 사용해야 하는 경우에도 민감 사용자 정보는 반드시 별도  암호화하여 토큰을 디코딩한 후에도 식별 불가하게 해야 한다.
  • JWT토큰을 탈취당할 경우 대처가 힘들기에 만료기간을 적절히 짧게 사용해야 하지만 JWT토큰 유효시간 무작정 짧게 설정 시 사용 편의성이 떨어질 수 있다. 이 경우에는 다음과 같은 방식을 통해 짧은 유효기간을 보완할 수 있다.
    • sliding session - 특정서비스를 계속 사용하는 유저에게 만료 시간을 연장
    • refresh token - 기존 access 토큰에 추가로 더 긴 만료기간의 refresh 토큰을 발급하여, access토큰 만료시 refresh토큰을 사용하여 새로운 access토큰을 발급

 

 

 

참고

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://dzone.com/articles/cookies-vs-tokens-the-definitive-guide

https://brunch.co.kr/@jinyoungchoi95/1

https://www.daleseo.com/jwt/#:~:text=JWT(Json%20Web%20Token)%EB%8A%94,%EC%A3%BC%EA%B3%A0%20%EB%B0%9B%EA%B8%B0%20%EC%9C%84%ED%95%B4%EC%84%9C%20%EC%82%AC%EC%9A%A9%EB%90%A9%EB%8B%88%EB%8B%A4.