-
안녕하세요.
이번 글은 로그인 구현에 많이 사용되는 JWT에 대해 이야기해보려 합니다.
인터넷에서 로그인 관련 구현을 살펴보다 보면 JWT구현을 많이 볼 수 있습니다.
저 또한 사이드 프로젝트에서 사용했던 로그인 방법이었습니다.
무엇이 JWT이고 세션이 무엇인지는 다른 글에서 많이들 알려주고 있으니 이 글에서는 생략하겠습니다.
이 글을 쓰게 된 이유는 우아한 형제들-동영상을 보던 중 궁금증으로부터 시작되었습니다.
동영상의 일부 중 JWT에 대한 설명 중 JWT를 도입하려면 매번 검사하는 것을 추천한다라는 내용이 나옵니다.
1. redis에 블랙리스트를 구현하여 검증
2. stateful token을 넣어 redis에 유효한지 검증
장점
해당 유효성 검증을 통해 써도 되는 토큰인지 안 되는 토큰인지만 판단하기에 statueful token 보다 부하가 적다는 것입니다
(statusful token의 단점은 매번 토큰 검사하고 user정보를 받아와야 한다)
궁금증
제 생각은 statusful token의 유효성 검사는 1,2번과 동일하고 user정보는 구현에 따라 세션/redis에도 저장이 가능합니다(ex. spring의 SessionAttributes)
그렇다면 JWT를 redis까지 넣어가며 사용하는 이점은 무엇인가?.
1.
서버의 리소스를 잡아먹는다면 JWT를 사용했으면서 JWT의 단점인 탈취 시의 취약점을 상쇄하고자 토큰 시간을 짧게 하고 리프레쉬 토큰을 도입하며 Redis까지 넣는다면 기존 세션과 다른 의미를 가질 수 있는 것인가?
2.
확장? 세션의 분산 서버 아키텍처는(Sticky Session과 Session Clustering) 복잡하여 토큰을 도입했지만 Redis를 쓴다면 세션 또한 Redis로 관리하면 어느 정도 복잡성이 줄어들 텐데?
그렇다면 JWT를 어떻게 사용하고 있을까?
JWT의 일반적인 구현
서버는 토큰을 발급하고 클라이언트는 토큰을 저장하고 필요할 때 헤더에 담아 사용합니다.
리프레쉬 토큰을 사용하는 경우
리프레쉬 토큰을 어디서 관리할 것이지에 따라 또 다릅니다.
클라이언트에서 관리할 경우는 토큰이 만료될 경우 클라이언트에 저장된 리프레쉬 토큰을 사용해 서버에 다시 요청하는 설계가 될 수 있습니다.
혹은 쿠키에 넣어 토큰 2개 다 넣어서 액세스 토큰 만료 시 리프레시 토큰으로 재발급할 수도 있습니다.
클라이언트는 정보를 JWT에서 뽑아 사용한다는 가정만 없으면
토큰을 Redis 없이 모두 클라이언트에 쿠키로 전달해 사용하는 것은(http only, sameSite) 좋은 시나리오 같습니다.
서버에 리프레쉬 토큰을 넣어 사용하는 경우는 인메모리 DB인 Redis를 많이 사용합니다.
이때 사용자가 만료되었을 경우 서버에 리프레쉬 토큰을 사용하여 다시 토큰을 재발급합니다.
클라이언트도 refresh token에 대한 어느 정도의 실마리는 가지고 있지만 백엔드 검증을 거친 후에 사용될 수 있습니다.
1. 토큰의 경우 탈취 가능성 때문에 유효시간을 짧게 한다
2. 그렇다면 사용자의 UX가 안 좋아지기 때문에 refresh token을 추가한다
3. refresh는 어디에 저장하냐에 문제도 있다.
4. 이를 서버의 원본을 저장하고 클라이언트에는 이를 찾을 수 있는 key를 발급한다.
5. 클라이언트는 토큰이 만료될 경우 key을 통해 서버에서 다시 토큰을 재발급받는다.
세션
세션은 위와 같은 방식으로 사용됩니다.
그렇다면 본론인 JWT + Redis VS Session의 경우 무엇이 다를까?
1.
서버의 리소스를 잡아먹는다면 JWT를 사용했으면서 JWT의 단점인 탈취 시의 취약점을 상쇄하고자 토큰 시간을 짧게 하고 리프레쉬 토큰을 도입하며 Redis까지 넣는다면 기존 세션과 다른 의미를 가질 수 있는 것인가?
토큰의 redis : 유효시간이 짧기에 refresh token을 저장해 놓고 있으며, 기존 token이 만료되면 접근한다
장점 : 토큰이 만료될 때만 redis에 접근한다. 단 black list용도로 쓸 경우는 세션과 동일하게 매 요청마다 접근한다
세션의 redis : 세션 정보를 저장하기 위함으로 도임, 매 요청마다 접근을 해서 세션정보를 가져온다
장점 : 쉬운 관리
생각해보니 token이 만료될 때만 접근하는 것과 세션을 통해 항상 물고 있는 것은 성능 차이가 발생할 수 있겠다는 생각이 듭니다.
2.
확장? 세션의 분산 서버 아키텍처는(Sticky Session과 Session Clustering) 복잡하여 토큰을 도입했지만 Redis를 쓴다면 세션 또한 Redis로 관리하면 어느 정도 복잡성이 줄어들 텐데?
토큰의 redis : refresh token을 저장하기 위함으로 도입
장점 : 토큰의 장점인 확장성을 살리며 단점인 유효시간을 커버한다
세션의 redis : 세션 정보를 저장하기 위함으로 도임
장점 : 분산 아키텍처에서 좀 더 쉬운 관리
사용할 때에 무엇을 선택하는지가 중요할 듯합니다.
++
2024.11.23
추가적인 생각입니다.
https://gisungcu.tistory.com/690
https://www.youtube.com/watch?v=XXseiON9CV0
'글또' 카테고리의 다른 글
StackOverflow가 DDOS를 대응하며 배운 것들 (0) 2022.10.24 StackOverflow는 9대의 on-prem 서버로 운영중 (0) 2022.10.24 인프콘을 보고 (0) 2022.09.23 레거시 코드를 대하는 법 (0) 2022.09.03 동시성 해결에 관해 (0) 2022.08.21