Node.js 账号关闭:token 吊销与延迟删除的三步法
客户支持系统里,账号关闭的难点在于决定什么必须立刻停、什么可以等。被盗的 refresh token 是即时滥用问题;账号删除请求是数据生命周期问题,恢复窗口完全不同。
短答案:保持稳定的 user ID;破坏性工作前先标记 profile 状态;被入侵就吊销所有会话;满足恢复与审计要求后再删除。Profile 状态与会话吊销是互补的控制,不是互斥的实现。
事故教训:关闭是两块钟
典型场景:支持代理报告客户的会话被从浏览器复制走,bot 已经在尝试 refresh 请求,同时客户要求关号。把两个请求都当"删用户"处理会造成竞态:攻击者可能在删除完成前一直持有有效会话;而匆忙删除可能毁掉调查事件所需的信息。
三步法(原文主线)
- 身份稳定优先:用 user ID 做主键,邮箱只是查找辅助——邮箱可改,ID 不可变;
- 先标记、后销毁:把 profile 状态先标记为关闭/停用,让业务逻辑立即拒绝访问,再做任何破坏性清理;
- 吊销与删除分离:被入侵时先吊销所有会话(即时止血),删除只在恢复期与审计要求满足后进行(数据生命周期)。
关键洞察:"关门"(revocation)与"拆屋"(deletion)是两个不同时间轴的时钟。把两者绑在一起,要么攻击者带着有效会话拖到删除完成,要么删除太快毁掉取证信息。
实践建议
- 账号关闭接口别一把梭"删用户":拆成 mark-shutdown(状态翻转)→ revoke-sessions(会话吊销)→ delete-after-audit(延迟删除)三个阶段;
- 被盗会话场景下吊销要即时且全局(所有设备、所有 token 类型),删除可以排队等审计;
- 主键永远用 user_id,别用邮箱或其他可变标识。
来源:Node.js Account Shutdown: Token Revocation and Eventual Deletion in 3 Steps - DEV Community