JWT 사용시 주의사항

J-USER·2023년 1월 2일
5

지개넓얕

목록 보기
5/5
post-thumbnail

Intro

흔히 사용자 인가 기능을 구현할때 크게 두가지 방법을 사용하는데, 바로 Session과 JWT 방식이다.

백엔드를 잘 접하지 않아도 jwt가 session 방식보다 많이 쓴다는것을 알것이다. 그렇다면 jwt는 무적인가? jwt를 클론코딩과 똑같이하거나, 단순 복붙을 한다면 사용자 정보와 관련된 문제이므로 장차 큰 문제로 이어질 수 있다.

그래서 jwt를 사용할때 주의할 점을 정리해보았다.

상상해보자

서울에 새롭게 J 놀이동산이 개장하였다. 이 놀이동산에 들어오기 위해서는 사용자는 입장권을 사야하고, 놀이동산 내에서 놀이기구를 탈때도 역시 직원이 사용자의 입장권을 확인하고 사용을 할 수 있다.
session 방식이든, jwt 방식이든 기본적인 원리는 입장권 형식으로 유사하다. 그러나 차이점은 그 입장권에 적혀있는 정보 이다.

Session 방식

session 방식은 입장권에 많은 정보가 있지않다. 발급 번호 딱 한줄이 있다.

그럼 어케 구분하는데???

입장권을 직원에게 제시하면, 직원은 입장권 발급 목록 같은 장부를 확인하여 이 사용자가 올바른 사용자인지 확인을 하게 된다.

여기서 장부를 session storage 이라고 한다.

JWT 방식

jwt 방식은 입장권에 적혀있는 정보가 제법 많이 있다. 유저의 발급일, 유효기간 등등... 그래서 직원은 입장권 하나만 보고 유효한지 안한지 판단을 하고 인가를 내려주게 된다.

아니 그럼 JWT가 무조건 좋아보이는데??

이게 JWT의 장점입니다. 사용자가 1억명이면 왜인지 확실하게 상상할 수 있을것이다.
그렇다면 JWT가 어떻게 생겼는지 맛만 보자

헤더에 기본 세팅값을 적어주고, Payload에 입장권에 적을 정보를 입력해주면 정보를 문자열로 암호화 하게 된다. 그리고 secret 값을 추가로 설정해주면 전혀다른 문자열 값을 얻을 수 있다. 그래서 위조 여부도 쉽게 알 수 있다.

JWT 주의사항

JWT를 많이 사용하며 대게 많은 백엔드 클론 코딩에서도 이를 사용하고 있는데, JWT도 문제점이 많기 때문에 이를 꼭 인지하고 사용했으면 좋겠다.

  1. alg : none
    none으로 알고리즘란을 적고 jwt를 만들어서 서버로 보내는 악성 유저가 있다. 왜 이런짓을 하냐면, 가끔 어떤 사이트들은 alg 가 none일 경우 인가를 해주는 경우가 있기 때문이다. 그래서 alg : none일 경우 이를 막아주는지 확인을 해야한다. 그러나 최근 라이브러리들은 이런 걱정 필요없다.

  2. JWT Decoding
    JWT는 decoding이 쉬운 편이다. 그래서 JWT에 사용자의 민감한 정보를 많이 넣는것은 주의하고 최소한의 정보만을 넣어야한다.

  3. 시크릿키 문제
    JWT를 구현하게 될때 시크릿키를 개발자가 지정할 수 있는데, 이 시크릿키를 대충 구현하는 개발자들이 많다. 매우 짧은 문자를 적는 경우도 있고, 특히 클론 코딩이나, 코드를 붙여오는 경우도 그렇다. 대충 적으면 때려맞추기가 아주 쉬워서 Brute force 공격이 이 허점을 이용하기도 하고 유명한 블로거, 유튜버에서 만든 시크릿키를 그대로 넣어서 공격하기도 하니 주의하도록 하자..

아니 주의만 주지말고 그럼 어떻게 하라는건데??

일단.. 1) 키를 매우 길게 설정한다. 2) 공유 금지 3) 생성용키/검증용키 2개 사용 (jwt 라이브러리에 있으니 적극 사용해보자!)

  1. JWT 탈취
    만약 누가 JWT를 탈취한 경우는 어떻게 될까?

놀이동산에 입장권 누가 훔쳐가면 누구탓? 카드 잃어버리면 누구탓? 물론 사용자 탓이지만... 개발자가 조치는 취해야함...

카드사라면 사용 정지를 시킬 수 있지만, JWT는 발급한것을 다시 회수하거나 사용 정지시킬 수 없다. (주면 끝이기 때문에..)

그럼 손 놓고 있냐?

일단 1) 탈취하기 어렵게 만드는게 중요하다. 훔치기 힘든 저장소 (http only cookie) 에 jwt를 저장해둔다. 2) JWT 블랙리스트를 따로 운영하는 것이다. 그러면 사용 정지를 모방할 수 있다.

??? 아니 그럼 블랙리스트가 커지면 session이랑 다를게 뭐냐???

그래서 나온 솔루션이 3) JWT 유효기간을 짧게 설정한다. 유통기한을 매우 짧게 설정해서 조금더 안전해질 수 있다.

그러면 사용자도 짧게 이용하잖아 ㅋㅋㅋㅋㅋ

그래서 JWT를 재발급시켜주는 refesh token을 따로 운영하면 된다.

refesh 토큰을 탈취하면??

그래서 refesh token rotation이라고 하는 정책을 운영하는데, 탈취 당한 유저가 refesh 토큰을 재발급하거나, refesh 토큰을 재사용하게 된다면 refesh token rotation을 요구하게 되는데, 이게 없다면 토큰을 발행해주지 않는다. 그래서 refesh 토큰을 1회용으로 설정하면 조금 더 안전한 JWT 사용이 가능해진다. 당근 라이브러리가 잘 되어있어서 잘 찾아보고 쓰면 될듯하다.

별일 없으면 session 방식으로 하는게 간단하고 안전하다. 회원이 아주 많을거같으면 or 마이크로 서비스가 많으면 JWT 사용하는 것이 바람직하다.

profile
호기심많은 개발자

0개의 댓글