[TIL] JWT(JSON Web Token)

Cottonmycotton·2021년 12월 12일
0

TIL

목록 보기
16/16

1. JWT(JSON Web Token)란?

JWT란 JSON 포맷을 이용하여 인증정보와 사용자에 대한 정보를 저장하는 Claim 기반의 Web Token이다. 말 그대로 유저 정보를 담은 JSON 데이터를 암호화 해서 클라이언트와 서버간에 주고 받는 것이다. 유저가 로그인에 성공한 후에는 access token이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 된다.

JWT는 수많은 프로그래밍 언어에서 지원이 된다.

  • C, Java, Python, C++, PHP, JavaScript, Go Swift, C# 등등...

access token을 생성하는 방법은 여러가지가 있는데 그 중 가장 널리 사용되는 기술 중 하나가 JWT이다. JWT의 특징은 가볍고, 토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위한 정보가 포함된다는 것이다. 즉 토큰 자체를 사용하는 자가 수용적인(Self-Contained) 방식으로 정보를 안전하게 전달한다.

  • Claim이란?
    • 클레임이란 사용자의 정보나 데이터 속성 등을 의미한다. 클레임 토큰의 토큰 안에 정보를 담을 수 있는 특징이 있다. 과거 일반 토큰 기반은 의미가 없는 문자열 기반으로 구성되있다.

어플리케이션이 실행될때 JWT를 static 변수와 로컬 스토리지에 저장하게 된다.

  • static 변수란?
    • 고정되어 변경 불가능한 변수. static변수에 저장되는 이유는 JWT를 HTTP헤더에 담아서 보내야 하는데 이를 로컬 스토리지에서 계속 불러오면 오버헤드(과도한 메모리 또는 시간)가 발생하기 때문이다.
  • 정리
    • JSON 포맷을 이용하여 인증정보와 사용자에 대한 정보를 저장하는 claim기반의 Web Token.
    • 토큰 기반의 인증 시스템에서 주로 사용된다.
    • 자가 수용적인(Self-Contained)방식으로 정보를 안전하게 전달한다.

2. JWT 구조

JWT는 Header, Payload, Signiture 이렇게 세부분으로 나누어지며 JSON 형태인 각 부분은 Base64로 인코딩 되어 표현된다. 각 부분을 이어주기 위해 . 구분자를 사용한다. Base64는 암호화된 문자열이 아니고, 같은 문자열에 대해 항상 같은 인코딩 문자열을 반환한다.

2-1. 헤더(Header)

토큰의 헤더는 typ와 alg 두 가지 정보로 구성된다. typ는 토큰의 타입을 지정한다. alg는 해싱 알고리즘을 지정하며 서명 및 토큰 검증에 사용된다.

2-2. 페이로드(Payload)

페이로드에는 토큰에 담을 정보가 들어있다. 여기에 담는 정보의 한 조각을 클레임이라고 부르고, name / value의 한 쌍으로 이루어져 다수의 정보를 담을 수 있다. 클레임의 종류는 크게 세 분류로 나누어진다.

1) 등록된(registered claim)클레임

등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰 정보를 표현하기 위해 이미 이름이 정해진 종류의 데이터들이다. 등록된 클레임의 사용은 모두 선택적이며, 이에 포함된 클레임 이름들은 다음과 같다.

  • iss : 토큰 발급자(issuer)
  • sub : 토큰 제목(subject)
  • aud : 토큰 대상자(audience)
  • exp : 토큰의 만료시간(expiration), 시간은 NumericData 형식으로 되어있어야 하며 언제나 현재 시간보다 이후로 설정되어 있어야 한다.
  • nbf : Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념이다. 이곳에서도 NumericData형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다.
  • iat : 토큰이 발급된 시간(issued at), 이 값을 사용하여 토큰의 age가 얼마나 되었는지 판단할 수 있다.
  • jit : JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용된다. 일회용 토큰에 사용하면 유용하다.

2) 공개(public)클레임

공개 클레임들은 공개용 정보를 위해 사용된다. 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 짓는다.

{
" https://niboo.velog.com ":true
}

3) 비공개(private)클레임

양 측간에(보통 클라이언트와 서버)협의하에 사용되는 클레임 이름들이다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할때 유의해야 한다.

{
"token_access": "niboo"
}

2-3. 서명(Signature)

JWT의 마지막 부분이다. 서명은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다. 서명은 위에서 만든 헤더와 페이로드의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀 키를 이용하여 헤더에서 정의한 알고리즘으로 해싱하고, 이 값을 다시 BASE64로 인코딩하여 생성한다.

3. 토큰 만들기

1) 유저가 로그인 했을 때 입력값이 DB의 회원정보와 일치할때 JWT를 발급한다.
2) Front-end에서는 JWT를 로컬/세션 스토리지에 저장한다.
3) 유저가 회원인증이 필요한 서비스에 접근했을 때 프론트에서는 요청을 보낼 때, header, authorization에 토큰앖을 담아 보낸다.
4) back-end에서는 받은 토큰 값을 복호화 하여 유저정보를 확인한다.
5) DB에서 해당 정보가 있는지 확인, 있다면 해당 서비스를 이용할 수 있도록 한다.


참고 자료
[Server] JWT(Json Web Token)란?

Django : Westagram #5 / 인증 / 인가 / JWT / Token

profile
투명인간

0개의 댓글