리프레시 토큰
리프레시 토큰 (Refresh Token)
액세스 토큰을 짧게 유지하면 보안에 좋지만, 그 대가로 자주 만료되어 사용자를 다시 로그인 시키는 문제가 생겨요. 이 둘 사이를 중재해 주는 게 바로 **리프레시 토큰(refresh token)**이에요. 리프레시 토큰은 사용자 재개입 없이 새 액세스 토큰을 얻기 위해 쓰는 문자열로, 클라이언트가 로그인 화면을 다시 띄우지 않고도 액세스 토큰을 갱신할 수 있게 해줘요. 곧 액세스 토큰 수명을 짧게 잡아도, 리프레시 토큰이 있으면 사용자 경험은 끊기지 않는 거죠.
누가 쓸 수 있나요
리프레시 토큰은 public 클라이언트와 confidential 클라이언트 모두 사용할 수 있어요. 다만 여기엔 보안상의 차이가 크게 갈려요.
- confidential 클라이언트 — 토큰을 쓰기 전에 인가 서버에 자기 신원을 인증해야 해요. 그래서 리프레시 토큰이 유출돼도 공격자가 그 토큰만으로는 실제 클라이언트인 척하기 어려워요. 위험이 상대적으로 낮죠.
- public 클라이언트 — 클라이언트 시크릿으로 스스로를 인증할 수 없어요. 그래서 리프레시 토큰이 유출되면 공격자가 클라이언트인 척 토큰을 그대로 쓸 수 있어요. 감지되지 않은 채 악용될 위험이 커요.
public 클라이언트에서 이 위험을 줄이는 방법 중 하나가 **DPoP(Demonstrating Proof of Possession)**예요. 리프레시 토큰을 특정 public 클라이언트 인스턴스에 묶어서, 다른 곳에서 토큰을 쓰면 검증에 실패하게 만들 수 있죠.
리프레시 토큰의 제약
리프레시 토큰에는 중요한 규칙이 하나 있어요. 원래 승인된 범위(scope)를 넘어서는 접근을 주면 안 된다는 것이에요. 즉 리프레시 토큰은 원래 부여된 권한을 벗어나 더 큰 권한을 얻는 수단이 되어선 안 된다는 뜻이에요.
그럼 왜 이런 토큰이 필요한 걸까요. 토큰의 목적은 곧 이렇게 정리할 수 있어요. 인가 서버가 액세스 토큰의 수명은 짧게 유지하면서도, 토큰이 만료될 때마다 사용자를 다시 개입시키지 않도록 해주는 것. 사용자는 한 번만 승인해 두고, 그 뒤의 갱신은 리프레시 토큰이 스스로 처리하는 구조인 거예요.
실제로는 액세스 토큰이 만료되면 클라이언트가 리프레시 토큰을 인가 서버의 token endpoint에 보내고, 그 대가로 새 액세스 토큰을 받아요. 이 교환 요청에는 grant_type=refresh_token과 리프레시 토큰 값이 포함되는 식이에요.