Post

JWT 토큰에 관하여

JWT 토큰에 관하여

사실 API를 다른 사람이 만들고 전달 받아서 적용 시키는 걸 안해봤습니다..

코딩을 접한지 어언 3년. 처음으로 코딩을 해본건 1년이 막 지난 지금, 더 이상 혼자서 개발을 하는것이 아니기에 신경을 써야하는것도, 공부 해야 하는것도 달라지는게 재미있습니다.

이번에 API를 전달 받아서, 더이상 퍼블리싱 작업이 아닌, 프론트엔드 작업을 제대로 시작하는데 모르는것 투성이 겠지만, 이렇게 공부해보면서 적용하는 걸 기록해볼 예정입니다.

백엔드 관련된 지식은 사실 학사과정에서 대부분 한번 씩 들어본, 공부해 본 것들이랑 overlap되는 경우가 있는거 같아, 살짝 다행..인거 같기도 합니다.


이번 글은 JWT (Json Web Token)에 대해서 알아보겠습니다.

API 문서를 보다가

1
2
3
4
{
  Authorization: 'Bearer YOUR_SECRET_TOKEN', 
    'Content-Type':'application/json'
}

저 SECRET_TOKEN은 어디서 찾나요 라고 백엔드 팀에게 문의한 결과 “아 이거 로그인 하면 나오는 것이고 지금 손보는중인데 JWT 공부하고 계시어요” 라고 말을 들어서 바~로 리서치를 시작하게 되었습니다.

일단 JWT는 언제 쓰이냐?

내 웹사이트의 컨텐츠를 로그인한 사람한테 (검증된 유저) 보여주고 싶을때, 세션을 사용하던지 토큰을 사용해서 구현 가능합니다.

일단, 유저는 사이트에게 login credentials을 보내고, 사이트는 허가증을 유저한테 주는데, 이 허가증을 유저가 사이트에서 무엇인갈 요청 할때 유저한테 보여달라 요구합니다. 허가증에 문제가 없으면, 사이트는 컨텐츠를 제공하는 방식이고요.

여기서 허가증에 무엇이 들어있는가로 세션이나 토큰을 나눌 수 있습니다.

일단 세션은 되게 짧은 정보를 허가증에 기록되어있어서, 사이트는 일일히 메모리나 DB에서 모든 데이터를 찾으며, 일치하는 허가증을 찾고, 맞으면 진행하는 방식이고요

토큰은 허가증 자체에 정보가 많이 내장되어있고, 유효기간 같은것만 슬쩍 보고 확인 후, 허가를 해줘, 진행시키는 방식입니다.

이것만 봐도 사실 장단점이 확 예상이 가는건 당연하겠죠

일단 장점으론, stateless하다는것입니다. 서버에 부담이 덜 간다는 거겠죠!

세션 방법을 쓰게될때, 많은 유저가 허가증을 들이내미게 되면, 하나하나씩 그 많은 허가증을 찾아가며 허가를 해줘야하니, DB도 커지겠고, 찾는 시간도 너무 걸리겠죠.

확실히 토큰은 유효기간 정도만 보고 허가를 해주면 되니 속도 차원에서도, 서버 늘리는데 들어가는 비용같은것도 많이 세이브 되겠네요.

단점으론 심각한 보안 이슈가 생기는건 문제입니다

일단 JWT 토큰은, 기본 셋팅과 데이터, 시그니처를 인코딩 해버린것 입니다, 그래서 데이터를 정말 하나만 바꿔도 JWT가 바뀌어서 위조를 막아주는데요,

4가지 취약점이 있습니다.

  1. 기본 셋팅값의 “alg” (algorithm) 부분을 “none” 으로 해놓고 서버에 보내는 악성 유저가 있답니다, 간혹 서버들은 none을 가지고 있는 허가증을 허가 해주어서 이런다고 하네요
  2. 디코딩이 매우 쉽습니다, 그래서 민감한 정보를 절대 넣으면 안된답니다, 최소한의 정보를 유지해야 한다고 하네요.
  3. 시크릿키 문제도 잇습니다, 개발자 마음대로 시그니처에 시크릿키를 짧게, 유추하게 쉽게 (brute force attack으로)써버리는 경우가 많아 쉽게 뚫린답니다.
  4. JWT 탈취도 있는 문제입니다, JWT는 서버에서 도난당한걸 알아도 허가증 취소 같은걸 못해서 (세션은 가능) 막을 방법이 없습니다. 유효기간 지날때까지 기다ㄹㅕ..

물론 예방을 잘 해놓으면 어느정도 보완이 됩니다 일단 none을 예외시키지 않는 코드를 작성하던지, 최신 라이브러리를 쓰면 막을 수 있고요, 최소한의 중요하지 않은 기본 정보만 넣는 걸 유지하고, 시크릿키도 길게 혹은 private, public 키 2개를 만들어서 나눠 보관하고, 훔치기 어려운 저장서 (HttpOnly cookie 같은곳)를 가져다 쓰면 훔치기 어려워지고, JWT에 짧은 유효기간을 넣어주며, refresh token을 같이 발급해줘서 새로운 토큰을 발급받게 해주고, 이것 또한 탈취 가능성이 있기에 Refresh Token Rotation도 (refresh token을 1회용으로) implement하면 좋다고 합니다.

기본적인 JWT에는 보안기능이 딱히 없어서 직접 개발을 해야한다고 합니다 (백엔드팀 화이팅)

This post is licensed under CC BY 4.0 by the author.