1. Refresh Token을 저장하는 이유
Access Token은 Rest API로 개발할 경우, FE 개발자가 관리하기 때문에 BE 개발자가 따로 관리할 필요가 없다.
다만, Refresh Token의 경우 FE 개발자에게 보내지 않기 때문에 BE 개발자가 서버의 stroage에 따로 저장해서 이후 검증에 활용해야 한다.
Refresh Token을 저장해서 관리한다는 것은 추가적인 I/O 작업이 필요하다는 의미이다.
따라서 I/O 작업이 필요없는 빠른 인증 처리를 장점으로 내세우는 JWT의 스펙과 상반되서 고민거리가 되곤 한다.
- Refresh Token은 탈취되어서는 곤란하므로 클라이언트는 보안이 유지되는 공간에 이를 저장해두어야 한다.
- Refresh Token은 서버에서 따로 저장을 하고 강제로 토큰을 만료시킬 수 있어야한다.
즉, 정리하면 JWT의 기본 장점을 보았을 때 서버에 저장할 필요가 없고 다른 곳에 저장해도 된다는 것이다.
따라서 Redis에 저장한다.
2. Redis에 저장하는 이유
Redis는 In-memory Data structure Store 로, 메모리 상에 데이터를 저장한다.
기본적으로 모든 데이터는 Key-Value 쌍을 이루며, 휘발성으로 저장하지만 매우 빠른 엑세스 속도를 가진다.
1) 빠른 엑세스 속도
Refresh Token을 이용한다는 것은 추가적인 I/O 작업이 필요하다는 의미이다.
이때 디스크에서 읽어오는 것이 아니라 메모리에서 바로 읽을 수 있기 때문에 빠르게 처리할 수 있다.
그래서 로그인 시 병목 현상을 줄일 수 있다.
2) 토큰 만료
Refresh Token은 만료시간이 있다. Refresh Token을 일반적인 DB에 저장하면, 스케줄러로 주기적으로 만료된 토큰을 제거해야한다.
하지만, Redis는 값을 저장할 때 데이터 유효기간(time to live)을 지정할 수 있다.
// 'EX' 파라미터를 넣으면 밀리세컨드가 아닌 초 단위를 사용함
// 30일로 설정했음
redisCli.set(String(userObj.id), refreshToken, 'EX', 30 * 24 * 60 * 60);
위 사진처럼 다양한 옵션이 있으므로 선택할 수 있다.
3. Redis 사용법
기본적인 세팅법 까지는 다른 블로그들에서도 많이 정리해놨으니 설명하지 않겠다.
1) 저장
const expirationInSeconds = 30 * 24 * 60 * 60;
redisCli.set(String(userObj.id), refreshToken, 'EX', expirationInSeconds);
위코드처럼 set 메서드를 사용해서 key로 userId를 사용하고, value로 refresh token을 사용했다.
참고로 나는 이 코드를 로그인 service 레이어에 추가했다.
2) 제거
// redis에서 refresh token 제거
redisCli.del(String(userId));
del 메서드를 사용해서 간단하게 key를 가지고 제거할 수 있다.
참고로 이 코드를 로그아웃, 회원탈퇴 service 레이어에 추가해서 사용했다.
참고
'JaveScript > ExpressJS' 카테고리의 다른 글
유효성검사 중복코드 리팩토링하기 (0) | 2024.03.26 |
---|---|
if-else => switch-case 리팩토링 (0) | 2024.03.25 |
ExpressJS와 ChatGPT 연동 (2) (1) | 2023.12.26 |
ExpressJS와 ChatGPT 연동 (1) (2) | 2023.12.18 |
닉네임 랜덤 제너레이터 (0) | 2023.12.17 |