Skip to content
isdnetworks
Go back

세션보다 오래 사는 토큰

인증을 토큰 방식으로 바꾸면서 서버가 상태를 안 갖게 됐고 세션 저장소도 필요 없어졌다. 그 상태에서 로그아웃을 구현하다 막혔다.

Table of contents

Open Table of contents

지울 것이 없는 로그아웃

세션 방식이면 서버의 세션을 지우는 것으로 로그아웃이 끝난다. 토큰 방식은 토큰이 클라이언트에 있고 서버가 아무것도 갖고 있지 않다.

클라이언트에 지우라고 할 수는 있지만 그것은 요청일 뿐이다. 이미 발급된 토큰은 만료 전까지 유효하므로 복사해 뒀다면 로그아웃 뒤에도 쓸 수 있다.

세 가지 대응과 선택

만료를 짧게 하면 위험 구간이 줄지만 갱신을 자주 해야 한다. 차단 목록을 두면 확실하지만 매 검증에서 저장소를 봐야 하므로 무상태라는 장점이 사라진다.

세 번째는 짧은 접근 토큰과 긴 갱신 토큰으로 나누고 로그아웃에서 갱신 토큰만 무효화하는 방식이었다. 접근 토큰 검증은 매 요청이고 갱신은 가끔이므로 자주 하는 것을 싸게 두고 드문 것을 비싸게 두는 셈이 된다.

갱신 시 회전이 만드는 신호

갱신 토큰을 쓸 때 새 것으로 바꾸고 옛 것을 무효화하게 했다. 한 번 쓰면 다시 못 쓰는 구조가 된다.

이렇게 하면 유출됐을 때 신호가 생기는데 공격자가 먼저 쓰면 정상 사용자의 갱신이 실패하고 반대면 공격자 것이 무효가 된다. 둘 중 하나가 반드시 실패하므로 그 실패 자체가 탐지 근거가 된다.

시계 차이와 허용 오차

토큰 만료는 시각으로 판단하므로 발급하는 쪽과 검증하는 쪽의 시계가 다르면 문제가 된다. 검증 쪽이 조금 빠르면 방금 발급한 토큰이 아직 유효하지 않다고 거부될 수 있다.

유효 시작 시각 검사에 짧은 여유를 뒀고 시계 동기화 상태도 함께 확인했다. 오차가 크면 여유로 덮을 수 없으므로 여유는 동기화의 대체물이 아니다.

토큰에 담을 것을 고른다

토큰에 정보를 넣으면 매번 조회하지 않아도 되지만 두 가지 이유로 담을 것을 줄였다. 토큰은 매 요청 헤더에 실리므로 커지면 전송량이 늘어난다.

더 중요한 것은 권한을 담으면 권한이 바뀌어도 만료 전까지 옛 권한으로 동작한다는 점이다. 바뀌면 만료까지 기다려도 되는 것만 담고 즉시 반영돼야 하는 것은 매번 조회하게 했다.

디버깅하려고 토큰을 로그에 찍을 뻔한 것도 여기서 걸렀다. 토큰은 자격증명이므로 로그에는 식별자만 남겨서 어느 토큰인지는 알되 그것으로 인증은 못 하게 했다.

정리


Share this post on:

Previous Post
브로커를 완충재로 쓸 때
Next Post
체인을 이긴 관계 테이블