下面整段是給執行 session 的 prompt。與 4a(capability)檔案面不重疊,但不要同時跑(同一 working tree)。 本波跨 BE+FE 兩 repo(FE:
~/Projects/Billows/Audit-Manager/compliance-manager-fe/,先讀其 CLAUDE.md;各 repo 分開 commit)。
【接手主題】FR-048 Phase 4b — 建 common/authz/signed_token.py(軸⑤ 短期簽章憑證),收掉五件瀏覽器原生 GET 免 bearer 端點
必讀:
docs/analysis/2026-07-07-unified-auth-guard-design.md §6(機制設計全文:發放/驗證/TTL/自我限定,照它實作)docs/claude/frontend-overview.md(FE 慣例);FE 前科:ffa01a78(盲加 JWT 打爆 window.open 下載)【branch】BE fix/v1.8.0-bugs;FE 用它當下 branch(不對停下問 user)。禁止切 branch。不動 jedi-* 套件。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 【1. common/authz/signed_token.py(機制本體,照設計 §6)】
itsdangerous.URLSafeTimedSerializer(已在依賴 2.2.0),key 自 JWT_SECRET 派生、scope 當 salt;payload {scope, resource_uid, user_id};TTL 預設 120 秒。issue_signed_token(scope, resource_uid) — 由帶 bearer 的發放端點呼叫,user_id 取 get_user_context()。@signed_token_required(scope=...) route decorator — 驗簽+scope+TTL(過期/偽造 → 401,新增 error code 一枚:error_code.py TOKEN 族或 AUTH_401 序號續編,遵守碼規範)+把 payload user_id 設進最小 context;同時把 payload 交給 view(供 resource_uid 比對)。【2. 五件逐一(每件都是「發 token 端點+資源端點掛 decorator+FE 改呼叫」三步)】
| # | 端點 | 特殊要求 |
|---|---|---|
| 1 | GET /otp-qrcode/<uid>(user-profile#3) |
自我限定:發放時 resource_uid=發放者本人 uid;驗證端比對 path uid == payload resource_uid → 只能拿自己的 QR(修掉「知 uid 拿他人 TOTP」的原洞,不只加認證)。FE:UserProfileForm.vue <img :src> 先打發放端點換 token 再組 src |
| 2 | GET /oscal-framework-version/download/oscal/<uid>(compliance-framework-manage#5,ffa01a78 前科件) |
發放端點掛 @jwt_required(登入即可讀,與 FR-042 政策一致)、token 綁 framework_version uid。FE:window.open 前先換 token 帶 ?st= |
| 3 | GET /file/download/<uid>+/file/pdf-preview/<uid>(D14 新發現,影響面最廣) |
先盤 FE 全部 call site(grep api.js+全 repo 用點):axios blob 的呼叫方不用動(可同時掛 @jwt_required 相容雙軌——st 參數與 bearer 二擇一驗);原生呼叫(window.open/<img>/<iframe>)逐個改走 token。雙軌驗證設計:decorator 先驗 ?st=,無 st 時 fallback 驗 bearer(都無 → 401),避免一刀切改壞 axios 呼叫方 |
| 4 | GET /survey/import-template(window.location LIVE:BatchImportDialog) |
token 綁 scope 即可(靜態範本無 resource);FE 改先換 token |
| 5 | GET /task-survey/import-template/<task_uid>(唯一 consumer 在 _archived) |
先確認無 live consumer:若確認 dead → 直接掛 @jwt_required() 即可(比照矩陣處置原則,不必上 token);有 live 才走 token |
【3. e2e 回歸(設計 §6 明定必附)】
前科件(#1 #2)在 ~/Projects/Billows/Audit-Manager/compliance-manager-test/ 補 e2e:登入 → 個人資料頁 QR 圖有載出、框架管理頁 OSCAL 下載成功。做不完至少给出手測 checklist 逐步驟(含「登出狀態直接打資源 URL → 401」的負向案)。測試專案慣例讀其 CLAUDE.md。
【4. 驗證+收尾】