[네트워크] JWT 토큰

임승민·2023년 2월 25일
0

네트워크

목록 보기
1/9
post-thumbnail

JWT(Json Web Token)는 인증에 필요한 정보들을 토큰에 담아 암호화 시켜 사용하는 토큰이다.

앱은 쿠키,세션이 없어 앱과 서버가 통신, 인증할 때 많이 사용된다.

세션과 다른 점은 서명된 토큰이라는 점 그리고 유저 데이터를 유저가 관리해 서버 부담을 줄일 수 있다는 것이다.

JWT는 사용자 자신은 토큰을 볼 수 있지만 수정은 불가하며 수정은 서버를 통해서만 가능하다.

JWT 구성

JWT는 3마디로 나뉜다.

{Header}.{Payload}.{Signature}
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header: 데이터 타입, 암호, 알고리즘 정보

Payload: 토큰에 담을 정보

Signature: 서명


Header에는 2가지 정보가 있다.

{
  "alg": "HS256",
  "typ": "JWT"
}
  1. alg: Signature를 만드는데 사용될 알고리즘의 종류이다. (암호화 방식 선택 가능)
  2. typ: 토큰의 타입이 들어간다.

Payload

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
  • Header, Payload는 암호화가 되어있지 않고 Base64로 인코딩 되어있다. 반대로 디코딩 하면 JSON형식으로 정보가 들어있다.
    • 따라서 민간함 정보는 담지 않는다.
  • key-value 형식으로 이루어진 한 쌍의 정보를 Claim이라하며 Payload에는 토큰에서 사용할 정보의 조각들인 Claim이 담겨있다.

claim은 크게 세가지로 나뉜다.

  1. 등록된 클레임 2. 공개 클레임 3. 비공개 클레임

등록된 클레임

이름이 정해진 클레임들이며 선택적으로 사용할 수 있다.

  • iss (issuer): 토큰 발급자
  • sub (subject): 토큰 제목
  • aud (audience): 토큰 대상자
  • exp (expiraton): 토큰의 만료시간
  • nbf (Not Before): 토큰 활성화 날짜
  • iat (issued at): 토큰이 발급 시간
  • jti (JWT id): JWT 식별자

공개 클레임

공개용 정보를 위해 사용되며 충돌 방지를 위해 URI형식으로 이름을 짓는다.

{"https://google.com": true}

비공개 클레임

서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다.

{"token_type": "access"}

Signature

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
	secret-key
)
  • Header, Payload는 암호화 돼있지 않아 제 3자가 복호화 및 조작할 수 있다.
    • 하지만 Signature는 서버에서 관리하는 비밀키가 유출되지 않는한 복호화할 수 없다.
  • Signature는 Header, Payload를 조합하고 비밀키를 알고리즘을 이용해 만든다.
  • 만약 JWT토큰 값을 수정해 서버로 보낸다면 서버는 Signature로 위변조 여부를 판단한다

JWT만 사용하면 될까?

JWT는 장점이 많지만 그렇다고 세션보다 모든면에서 우수한 것은 아니다.

데이터 길이가 길어서 인증 요청이 많아지면 네트워크 부하가 발생할 수 있다.

세션은 모든 사용자의 상태를 기억해서 고려할게 많지만 가능하다면 사용자 상태를 제어할 수 있다.

  • ex) 다른기기의 로그인 관리

만약에 JWT가 탈취를 당한다면 통제를 할 수 없어 아무런 조치를 할 수 없다.

Access토큰과 Refresh토큰

위의 문제점을 보완하기 위해 access토큰과 refresh토큰을 사용한다.

  1. 서버는 access토큰, refresh토큰을 발급한다. 이때 refresh토큰은 서버측 DB에도 저장된다.
  2. 사용자는 access토큰의 만료기간이 지나면 refresh토큰을 보낸다.
  3. 서버는 DB에 있는 값과 비교해 맞다면 새 access토큰을 발급 한다.

Access 토큰: 유저의 정보가 담긴 토큰, 토큰으로 사용자 정보에 맞게 응답을 진행한다.
Refresh 토큰: 새로운 access 토큰을 발급해주기 위해 사용하는 토큰이다.

JWT 인증 과정

  1. 사용자가 서버에 로그인을 요청한다.

  2. 서버에서 인증 요청을 받으면, Header, Payload, Signature를 정의하고 이것들을 Base64로 한 번 더 암호화하여 JWT를 생성하고 이를 쿠키에 담아 클라이언트에게 발급한다.

  3. 클라이언트는 받은 JWT를 브라우저 저장소에 저장한다.

  4. 서버에 요청 시 헤더에 토큰을 담아서 보낸다.

  5. 서버는 요청을 받을 때마다 비밀키를 사용해 토큰이 유효한지 검증한다.

  6. 만약 액세스 토큰의 시간이 만료되면 리프래시 토큰을 이용해 서버에게 새 엑세스 토큰을 발급 받는다.

0개의 댓글