fix(auth): 令牌到期自动续上,不再用半小时就被踢回登录页
CI / backend (push) Canceled after 0s

服务端一直签 access(30 分钟)和 refresh(14 天)两个令牌,但两个客户端拿到 401 都是直接清
令牌跳登录页,refresh 从来没被用过——"14 天有效"只是纸面参数,真实寿命就是 30 分钟。

- web/client.ts:请求前剩不到 90 秒先换;撞 401 先换再重放一次原请求;并发共用一次刷新;
  上传附件同一条路
- android/Api.kt:call 拆 call/callOnce,2002 时用 Mutex 串行刷新后重放
- 后端 /auth/refresh 看一眼账号状态:停用的账号不能靠 refresh 一直续(2012)
- 新增 session-refresh.mjs:假 access + 真 refresh 要能留住人,两个都假才回登录页
This commit is contained in:
Steven
2026-11-03 22:53:43 +08:00
parent 02ef47e753
commit 2c338490e5
7 changed files with 329 additions and 21 deletions
+16
View File
@@ -70,6 +70,22 @@ async def test_refresh_returns_working_token_pair(client: AsyncClient) -> None:
assert me.status_code == 200
async def test_disabled_account_cannot_refresh(client: AsyncClient) -> None:
# 停用的账号不能靠 refresh 一直续下去:令牌在有效期内也要挡住
user = await login(client, "13800000009")
from app.db import SessionFactory
from app.models import AppUser
async with SessionFactory() as session, session.begin():
row = await session.get(AppUser, user["user_id"])
assert row is not None
row.status = "disabled"
resp = await client.post("/api/v1/auth/refresh", json={"refresh_token": user["refresh_token"]})
assert resp.status_code == 403
assert resp.json()["code"] == 2012
async def test_requires_token(client: AsyncClient) -> None:
resp = await client.get("/api/v1/auth/me")
assert resp.status_code == 401