JWT란 JSON 포맷을 이용하여 인증정보와 사용자에 대한 정보를 저장하는 Claim 기반의 Web Token이다. 말 그대로 유저 정보를 담은 JSON 데이터를 암호화 해서 클라이언트와 서버간에 주고 받는 것이다. 유저가 로그인에 성공한 후에는 access token이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 된다.
JWT는 수많은 프로그래밍 언어에서 지원이 된다.
access token을 생성하는 방법은 여러가지가 있는데 그 중 가장 널리 사용되는 기술 중 하나가 JWT이다. JWT의 특징은 가볍고, 토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위한 정보가 포함된다는 것이다. 즉 토큰 자체를 사용하는 자가 수용적인(Self-Contained) 방식으로 정보를 안전하게 전달한다.
어플리케이션이 실행될때 JWT를 static 변수와 로컬 스토리지에 저장하게 된다.
JWT는 Header, Payload, Signiture 이렇게 세부분으로 나누어지며 JSON 형태인 각 부분은 Base64로 인코딩 되어 표현된다. 각 부분을 이어주기 위해 . 구분자를 사용한다. Base64는 암호화된 문자열이 아니고, 같은 문자열에 대해 항상 같은 인코딩 문자열을 반환한다.
토큰의 헤더는 typ와 alg 두 가지 정보로 구성된다. typ는 토큰의 타입을 지정한다. alg는 해싱 알고리즘을 지정하며 서명 및 토큰 검증에 사용된다.
페이로드에는 토큰에 담을 정보가 들어있다. 여기에 담는 정보의 한 조각을 클레임이라고 부르고, name / value의 한 쌍으로 이루어져 다수의 정보를 담을 수 있다. 클레임의 종류는 크게 세 분류로 나누어진다.
등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰 정보를 표현하기 위해 이미 이름이 정해진 종류의 데이터들이다. 등록된 클레임의 사용은 모두 선택적이며, 이에 포함된 클레임 이름들은 다음과 같다.
공개 클레임들은 공개용 정보를 위해 사용된다. 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 짓는다.
{
" https://niboo.velog.com ":true
}
양 측간에(보통 클라이언트와 서버)협의하에 사용되는 클레임 이름들이다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할때 유의해야 한다.
{
"token_access": "niboo"
}
JWT의 마지막 부분이다. 서명은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다. 서명은 위에서 만든 헤더와 페이로드의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀 키를 이용하여 헤더에서 정의한 알고리즘으로 해싱하고, 이 값을 다시 BASE64로 인코딩하여 생성한다.
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