예전부터 python(비단 파이썬에서만 아니고 java등 모든 언어)에서 암호 token을 만드는 기술들은 많았다. 하지만 이전에는 암호화에만 포커스가 맞추어져 있고 만료 시간 등의 개념을 반영하려면 다소 트윅이 필요했다.

JWT(Json Web Token)은 token제작시 과거의 다소 부족했던 부분들을 반영하여 스팩으로 만들었다. 큰 특징을 보면 다음과 같다.

  • JSON형식의 데이터 지원
    • decode를 하면 json형식으로 그대로 풀린다.
  • 토큰의 각종 claim 지원
    • Expiration Time Claim(exp)
    • Not Before Time Claim(nbf)
    • Issuer Claim(iss)
    • Audiece Claim(aud)
    • Issued At Claim(iat)
  1. Expiration Time Claim(exp)
    • 말 그대로 토큰의 만료 시간을 설정하는 영역이다.
  2. Not Before Time Claim(nbf)
    • 위 exp와는 반대되는 개념으로 토큰이 비유효한 시간을 지정하는 영역이다.
  3. Issuer Claim(iss)
    • 토큰의 발행자를 지정하는 영역이다.
  4. Audiece Claim(aud)
    • 토큰의 수신인 영역이다. 수신인만 key를 가지고 decode할 수 있다.
  5. Issued At Claim(iat)
    • 토큰이 만들어진 시간을 설정하는 영역이다.

세부 사용법들은 참고 URL을 확인하기 바란다.

일단 exp및 aud필드를 활용하여 간단하게 토큰을 이용한 인증 요청 기본 플로우를 그려보았다.

sequenceDiagram; client ->> server : token요청(여기서 client의 정보 넘어감(ID등)); server -->> client : token발급(exp, aud설정); client ->> client : Token 저장 ; Note over client, server : 서버에 기능 요청시; client ->> server : token; server ->> server : ID 및 exp 확인; alt is OK; server -->> client : result data + new exp 전송; else is Not OK; server -->> client : 만료 err ; client ->> server : token 연장 요청; server -->> client : token발급(exp연장됨, aud설정); end;

@ 주의 : aud = [클라이언트ID, 서버ID]로 지정해야 한다.

여기서 주의할 부분은 바로 token의 연장 요청 부분이다. 만료된 토큰만 가지고 서버에 보내서 연장이 가능하다면, 누군가가 토큰만 캡쳐하여 요청만 보내면 쉽게 서버의 서비스에 접근이 가능하다.

이에 refresh토큰을 미리 하나 더 만들어 놓고, 메인 토큰의 연장 요청시 이 refresh토큰이 없으면 연장이 안되도록 하는 방법을 많이 사용한다. 이 refresh 토큰의 exp값은 메인 토큰의 exp보다 아주 길다. (사실 refresh토큰을 캡쳐하여 접근한다면 문제가 또 되기 때문에 근본적인 해결은 아니다. 하지만 허들을 하나 더 만들어 놓는다는데 의의가 있는 것 같다)

이를 반영하여 다시 그려보면 다음과 같다.

sequenceDiagram; client ->> server : token요청(여기서 client의 정보 넘어감(ID등)); server -->> client : token발급(exp, aud설정); server -->> client : refresh token발급(long exp, aud설정); client ->> client : Token 저장 ; Note over client, server : 서버에 기능 요청시; client ->> server : token; server ->> server : ID 및 exp 확인; alt is OK; server -->> client : result data + new exp 전송; else is Not OK; server -->> client : 만료 err ; client ->> server : token 연장 요청(with refresh token); server -->> client : token발급(exp연장됨, aud설정); end;

참고 : https://pyjwt.readthedocs.io/en/stable/index.html