eatthefrog

[Security] Access Token과 Refresh Token, 왜 둘 다 써야 할까? 본문

백엔드 노트

[Security] Access Token과 Refresh Token, 왜 둘 다 써야 할까?

eater_forg 2026. 1. 4. 13:58

웹/앱 서비스를 개발하다 보면 인증(Authentication) 단계에서 늘 마주치는 주제가 있습니다. 바로 Token입니다. 단순히 token 하나만 쓰면 편할 것 같은데, 왜 굳이 refreshToken까지 챙겨야 할까요?


1. 왜 그냥 token 말고 refreshToken을 넣어야 하나요?

이건 마치 **'놀이공원 자유이용권'**과 **'신분증'**의 관계와 같습니다.

  • Access Token (자유이용권): 놀이기구(서버 데이터)를 탈 때마다 보여줘야 합니다. 하지만 분실하면 누구나 이용할 수 있어 위험하죠. 그래서 유통기한을 아주 짧게(예: 1시간) 설정합니다.
  • Refresh Token (신분증): 자유이용권이 만료되었을 때, 매표소(서버)에 가서 "제 신분증 여기 있으니 자유이용권 새로 끊어주세요!"라고 말할 때 사용합니다.

정리하자면: > RefreshToken 뮤테이션의 목적은 **"만료된 자유이용권을 갱신하는 것"**입니다. 증명서 역할을 하는 refreshToken(신분증)을 서버에 전달해야, 서버가 나를 믿고 새로운 Access Token을 발급해 줄 수 있습니다.


2. 왜 응답으로 두 토큰을 동시에 다시 보내주나요?

새로운 자유이용권을 받을 때, 신분증도 새것으로 교체해 주는 것과 같습니다. 이를 Refresh Token Rotation이라고도 부릅니다.

  1. 새로운 Access Token: 다시 서비스를 이용해야 하니 당연히 새로 받아야 합니다.
  2. 새로운 Refresh Token (보안 강화): 신분증도 한 번 쓰면 보안상 폐기하고, 더 안전한 새 신분증으로 교체해 주는 것입니다.

이렇게 하면 누군가 내 옛날 신분증(이전 Refresh Token)을 훔쳐가더라도 이미 무효화된 상태라 사용할 수 없게 되어 훨씬 안전해집니다.


3. 개발자의 단골 질문: 이름이 같은데 '순환 참조' 아닌가요?

코드상에서 refreshToken이라는 함수(Mutation) 안에 응답값으로 또 refreshToken이 들어있으면 "이거 무한 반복(순환 참조) 되는 거 아냐?"라는 의문이 생길 수 있습니다. 하지만 걱정 마세요! 이름만 같을 뿐, '종류'가 다릅니다.

① 이름은 같지만 '행동'과 '물건'의 차이

  • 바깥쪽 refreshToken: 토큰을 갱신해달라는 '명령어(함수/Mutation)'의 이름입니다.
  • 안쪽 refreshToken: 서버가 새로 발급해서 준 '글자 데이터(String)'일 뿐입니다.

비유: 아빠에게 "사과(명령어)"를 깎아달라고 했더니, 아빠가 깎아놓은 "사과(진짜 과일)"를 접시에 담아 주신 상황입니다. 이름은 같지만 하나는 행동이고 하나는 물건이라 서로 섞일 일이 없죠.


요약 및 결론

  1. 신분증(refreshToken)이 필요한 이유: 내가 진짜 주인임을 증명하고 안전하게 새 자유이용권을 받기 위해!
  2. 둘 다 다시 주는 이유: 보안을 위해 '신분증'까지 주기적으로 교체(Rotation)하기 위해!
  3. 순환 참조가 아닌 이유: 하나는 기능(함수)의 이름이고, 하나는 결과(데이터)의 이름일 뿐이기 때문!