🔥스파르타 TIL (Spring)

Redis를 활용한 BlackList 관리 중 깨달은 문제

승승장규 2025. 4. 23. 13:27

access_token이 노출이 되었다는 가정하에 BlackList에 등록해주는 기능을 구현하던 중 아무생각 없이 Redis에 저장하는 시간을 대충 저장하게 되면서 깊은 생각에 빠지게 되었다.

 

access_token을 Redis에 BlackList로 저장한 뒤, 만료시간을 사용자 정의로 지정해주면서 실제 BlackList에 등록된 access_token이 언제까지 유효한지 알 수 없다는 생각이 들면서 개선해보기로 마음을 먹었다.


Before
access_token을 BlackList로 관리하는 과정에서 임의로 1시간으로 지정함.
1. BlackList에 등록된 access_token이 언제 만료되는지 알 수 있는가?
2. BlackList에 등록된 access_token의 만료 시간이 BlackList에 등록된 만료시간 보다 길다면?
3. Redis는 인메모리 저장소라, 영속성이 없으면 서버 재시작 때 데이터 사라지므로 BlackList에 등록된 토큰이 다시 유효해진다면?


이와 같은 문제가 발생하는 것을 예방하기 위해 BlackList에 등록할 때 access_token의 만료시간과 현재시간을 사용해서 등록해주는 방식을 선택했다.


After
1. BlackList에 등록할 때 access_token의 만료시간과 현재시간을 뺀 뒤 1000으로 나눈 몫을 사용한다면? -> token의 만료시간은 보통 밀리세컨드 단위를 사용하기 때문에 1000으로 나눠서 초 단위로 사용함
2. 같은 토큰이 BlackList에 등록되어 있는지 검증하므로써 중복이 될 수 있는 문제를 차단

결론
JWT 방식의 취약점으로는 stateless한 구조 때문에 토큰의 무효화가 어렵다는 점이다. 이미 발급된 토큰을 누군가 악의적으로 가로채서 요청을 보내도 서버는 그저 응답을 줄 뿐이다.
이러한 문제를 해결하기 위해 BlackList에 토큰을 등록시켜 더 이상 요청을 응답하지 않게 막을 수 있고, 만료시간을 access_token의 만료시간으로 등록하게 되면서 이러한 문제를 해결할 수 있다.


1. access_token의 만료시간이 BlackList에 설정된 만료시간보다 짧을 경우 메모리를 계속 점유하고 있기 때문에 메모리 누수가 발생할 수 있는 문제
2. 반대로 access_token의 만료시간이 더 길다면 BlackList에서 해제된 뒤에도 계속 악의적인 요청을 할 수 있는 문제