진짜 개발자
본문 바로가기

IT Knowledge

ITKnowledge - 토큰기반 인증과 JWT

728x90
토큰기반 인증과 JWT

토큰 기반 인증

이번 시간에는 토큰기반 인증에 대해 알아보도록 하겠습니다.

 

 

1. 배경

토큰기반 인증이 생겨나게된 배경을 알기 위해서는 기존의 인증 방식이 무엇이 있었으며, 그것의 문제를 알게된다면 쉽게 이해할 수 있을 것입니다.

 

서버기반 인증의 문제


우선 토큰기반 인증이 발생하기 이전 가장 많이 사용되던 인증방식인 서버기반 인증의 문제점을 알아보겠습니다.가장 대표적인 문제점들은 아래와 같습니다.

 

세션


우선 세션의 경우 사용자의 인증 정보를 서버측 메모리에 저장하게 됩니다. 다양한 저장방법이 있지만, 문제는 서버측의 자원을 사용한다는 것 입니다. 이때 사용자가 적을때에는 문제가 없지만 사용자가 점차 증가하게 된다면, 서버측 메모리(자원)들이 부족하게 될 것입니다. 이 문제를 해결하기 위해서는 서버의 확장 및 업그레이드가 필요합니다. 각각 스케일 아웃, 스케일 업 이라고도 합니다.

 

확장성


사용자가 증가함에 따라 세션은 서버의 자원을 사용하기 때문에 앞서 말씀드린것 처럼 확장이 필요합니다. 하지만 세션은 확장의 문제를 안고 있습니다. 로드밸런싱을 위해 서버를 스케일 아웃(서버의 수를 늘림) 하는 경우 사용자는 한대의 서버로만 접속 되는 것이 아니라, 서로 다른 서버로 요청을 보내게 되는 경우가 있습니다. 이때 사용자가 이전 상태를 유지하기 위해서는 서로다른 서버간의 세션동기화 작업이 필요합니다. 이 때문에 서버기반 인증의 경우 확장의 불편함이 있습니다.

 

 

 

2. 토큰기반 인증

Stateless 서버의 경우 사용자의 요청이 이전 요청과 어떠한 관계와 종속이 되지 않는 서버를 의미합니다. 토큰기반 인증stateless 서버에 적합합니다.

 

2.1 Claim 토큰 그리고 Oauth 토큰

토큰에는 크게 두가지 종류가 있습니다. 바로 Claim, Oauth입니다.

 

Oauth


Ouath의 인증과정을 통해 발급되는 토큰의 경우에는 Random String으로 특별한 정보를 가지고 있지 않는것이 일반적입니다. 따라서 서버에서는 이토큰을 이용하여 다시 관련된 정보를 찾아야합니다.(서버에 부담)

 

Claim


Claim Token경우에는 토큰 자체에 필요한 정보들이 담겨있는 것으로 JWT가 대표적입니다.

Claim Token의 경우에는 위와 같이 토큰자체에 필요한 정보가 모두 담겨있기 때문에 별도로 관련된 정보를 검색하는 작업이 필요가 없다는 것입니다.

 

비교


https://bcho.tistory.com/999

 

 

2.2 Stateless 서버

바로 위와같이 토큰을 통해 인증이 가능하므로, 토큰 기반인증 서버의 경우 stateless 합니다. 사용자의 정보를 별도로 저장하거나 유지 및 관리할 필요가 없으므로, 1에서 다루었던 문제점들을 걱정할 필요가 없습니다.

 

 

 

3. JWT(Json Web Token)

JWT는 Json 형태를 띄는 Token으로 필요한 모든 정보를 가지고 있습니다. 이는 Http Header에 넣어 전달할 수 있으며 URL 파라미터로도 전달이 가능합니다.

 

3.1 JWT의 장점

자가수용적


JWT는 필요한 모든 정보를 자체적으로 지니고 있기 때문에, 서버에서 클라이언트의 정보를 저장 및 관리할 필요가 없습니다.

 

안정성


JWT에는 Sign 정보가 담겨있기 때문에, 보낸이가 바뀌었는지, 정보가 바뀌었는지를 검증할 수 있습니다.

 

 

3.2 JWT의 구조

JWT는 위와 같이 .을 구분자로 하여 크게 3가지 정보로 이루어져있습니다.

 

3.2.1 헤더(header)

헤더에는 두가지 정보가 담겨있습니다. typ(토큰 타입), alg(해시 알고리즘) 입니다. typ는 토큰의 타입(JWT)를 알려주며, alg는 해시 알고리즘을 정합니다.

 

3.2.2 정보(payload)

토큰에 포함될 정보가 담기는 곳입니다. 하나의 key, value 쌍으로된 정보를 claim 이라고 합니다. claim은 다시 3가지로 분류가 됩니다.

 

등록된 클레임(registerd claim)


등록된 클레임은 APP의 서비스에 필요한 정보가 아닌, 토큰의 정보를 표현하기 위한 claim 입니다. 모든 registerd claim들은 선택적(optional)입니다.

- iss : 토큰 발급자

- sub : 토큰 제목

- aud : 토큰 대상자

- exp : 토큰 만료시간 (거의 꼭 필요)

- iat : 토큰이 발급된 시간

- jti : JWT 고유 식별자

 

이중에서도 exp(토큰 만료시간)은 중요합니다. 아래에서 다시 다루도록 하겠습니다.

 

공개 클레임(public claim)


공개 클레임에 대해서는 아직 이해를 하지 못해서, 잘못된 정보를 드리는 것보다 추후 정확히 알게되면 수정을 하는것이 낫다고 판단하여 넘어가도록 하겠습니다.

 

비공개 클레임(private claim)


서비스에 필요한 정보들이 포함되는 claim으로 서버와 사용자간의 협의하에 작성됩니다.



3.2.3 서명(signature)

서명은, Token의 무결성을 보장하기 위해 사용됩니다. 무결성은 토큰의 내용이 위변조 되지 않았음을 증명하는것을 의미합니다.

JWT는 HMAC이라는 방법으로 서명을 하게됩니다. JWT token의 header와 claim을 인코딩한것을 다시 비밀키를 이용하여 해싱하하는 방식입니다.

이 때문에 비밀키를 알지 않는이상, 새로운 HMAC을 만들수 없으며, 복호화도 불가능합니다. 

 

 

3.3 JWT의 만료시간

앞서서 JWT의 등록된 클레임(registered claim)은 모두 선택적(optional)이라고 말씀드렸습니다만, exp(만료시간)의 경우에는 조금 중요하다고 했습니다. 그 이유는 아래와 같습니다.

한번 발급된 토큰은 값을 수정하거나 폐기가 불가


JWT는 토큰 내에 모든 정보를 다 가지고 있기 때문에, 한번 발급된 토큰에 대한 변경은 서버에서는 더 이상 불가능합니다. 토큰을 잘못 발행해서 삭제해야 하더라도, Signature만 맞다면 사용 가능한 토큰으로 인식을 하기 때문에, 서버에서는 한번 발급된 토큰의 정보를 바꾸는 일이 불가능합니다. 때문에, JWT를 쓴다면, Expire time을 꼭 명시해야 하며, refresh token등을 이용해서, 중간중간 토큰을 재발행하도록 해야 합니다. (하루 단위 정도?)

 

 

 

4. REST API 에서는 왜 토큰기반 인증을 사용할까?

REST API의 특징 중 Stateless라는 특성이 있습니다. 이는 사용자측의 상태정보를 서버측에 저장하지 않는 특성을 의미합니다. 따라서 REST API에서는 Session을 사용하지 않습니다. 이 때문에 토큰기반 인증을 사용하게 되었습니다.