JWT 구조 그리고 인증

민픽minpic·2023년 4월 17일
0

[TIL] Today I Learned

목록 보기
5/25

jwt에 대하여 TIL을 적고, 이후에 깨달은 사실이 한가지 있다.

jwt 관련하여 TIL을 정리하면서 나름 jwt에 대해 잘 알고 있다고 생각했지만, 다시 적어 놓은 TIL을 보니 중요한 것이 한가지 빠졌다는 것을 알게 되었다.

실제로 JWT 의 구조, 그리고 어떻게 인증하는지?

JWT 구조

JWT 의 구조는 "." 을 기준으로 3가지 영역으로 나뉜다.

헤더에서는 토큰의 타입과 알고리즘이 지정되어있다.
내가 미니프로젝트에서 만들어낸 토큰의 헤더에는 아래와 같이 담겨있었다.

내용에서는 토큰에 담을 정보가 들어있다.
내가 만든 토큰 기준으로 설명을 해보자면,

아래와 같은 정보들은 Registered claim 으로 토큰의 정보를 담기 위해서 이름이 이미 정해진 claim이다.

fresh 는 True 이면 새로운 토큰 발급이 필요하다는 의미이고, False 가 기본값이다.
fresh 는 flask_jwt_extended 라이브러리에서 사용하는 Private Claim 인 것 같다.
보통 클라이언트와 서버 협의하에 사용되는 클레임 이름이라 생각하면 된다.
이름 중복 주의~!

lat : 토큰이 발급된 시간, 해당 값을 사용해서 토큰이 발급한지 얼마나 되었는지 판단 가능
jti : jwt 고유 식별자, 주로 중복처리를 위해 사용된다. 
type : 타입
sub : 토큰제목 ( 내 아이디! )
nbf : NotBefore 을 의미함. 이 날짜가 지나가기 전에는 토큰이 처리되지 않는다.
exp : 토큰 만료 시간. 

다음은 서명데이터이다.
서명은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다.
서명은 위에서 만든 헤더와 페이로드의 값을 각각 인코드를 하는데, 내가 만들었던 토큰을 보면
HMACSHA256 알고리즘을 사용해서 아래와 같이 signature 이 나왔다.

헤더와 내용의 값을 각각 base64로 인코딩하고, 인코딩한 값을 비밀키를 이용해 헤더에서 정의한 알고리즘으로 헤싱한다. 이 값을 다시 base64로 인코딩하여 생성한다.

그리고 클라이언트에서 요청을 받을 때, 클라이언트가 전달해준 토큰을 서버가 가지고 있는 비밀키를 가지고 signature를 복호화 하고, base64UrlEncode(header)가 jwt 헤더와 일치한지, base64UrlEncode(payload)와 일치한지 확인하고 일치하면 인증을 허용한다.

애초에 비밀키는 서버만 가지고 있기 때문에 변조되었다면 인증이 되지 않을 것ㅊ이다.

서명은 메세지가 변조되지 않았는지 확인하는데 사용하고, 개인 키로 서명된 토큰의 경우 JWT의 발신자가 누구인지 확인할 수도 있다.

https://jwt.io/#debugger-io 웹사이트를 들어가면, 내가 발급받은 토큰에 대한 헤더,내용,서명에 대한 Json 데이터를 확인 할 수 있다.

profile
사진찍는 개발자 / 한 가지 개념이라도 깊이있게

0개의 댓글