Skip to content

fix(server): 브리지와 대시보드가 같은 계정 refresh token을 서로 무효화한다 (SYS) #271

Description

@kmjnnhyk

문제

refresh_token 테이블이 유저당 한 행이고 발급 때마다 회전한다(AuthService.issueTokensfindByUserId(...).map(rotate)). 그래서 같은 계정으로 브라우저 대시보드와 로컬 브리지를 동시에 쓸 수 없다.

  • 브리지는 3초마다 폴링하며 access token이 만료되면 refresh를 돌린다 → 회전으로 브라우저가 들고 있던 refresh token이 무효가 된다
  • 반대로 사용자가 브라우저에서 다시 로그인하면 브리지의 refresh token이 무효가 된다

먼저 만료된 쪽은 access token 30분이 지나는 순간 갱신에 실패하고, 대시보드는 RequireAdmin이 401을 받아 아무 안내 없이 로그인 화면이나 홈으로 튕긴다.

왜 이 조합이 필수인가

잡의 실행자는 버튼을 클릭한 사람이고(assigneeUserId), 브리지는 자기 소유 잡만 폴링한다. 따라서 브리지와 대시보드는 반드시 같은 계정이어야 한다. 계정을 나눠 회피할 수 없는 구조다.

재현

  1. admin@thumbsup.local로 대시보드 로그인
  2. 같은 계정으로 브리지 실행(pnpm start loginpnpm start)
  3. 30분 이상 두면 → 대시보드가 저작 화면 진입 시 튕긴다

로컬 e2e(이슈 258) 검증 중 실제로 발생했다. 브리지를 재기동해 토큰을 맞추면 임시로 해소되지만, 다시 30분 뒤 같은 일이 반복된다.

제안

  1. refresh token을 유저당 여러 개 허용한다. refresh_token에 디바이스/클라이언트 식별자를 추가하고 (user_id, client_id) 단위로 회전한다. 브리지는 bridge, 웹은 web으로 구분하면 서로 무효화하지 않는다. 근본 해결.
  2. 당장은 최소한 증상을 알려주기라도 해야 한다. 지금은 조용히 튕겨서 원인을 알 수 없다 — 재발급 실패 시 "다른 기기에서 로그인해 세션이 만료됐어요" 안내 후 로그인으로 보내는 처리가 필요하다.

관련: 이슈 258 로컬 e2e 검증 중 발견.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions