关联:Htpasswd 基础鉴权 · Web 登录鉴权 (Session, Cookie, Bearer, JWT)

发生条件

  • 后端给 /api/... 加了 HTTP Basic Authentication (HTTP 基础认证):未带凭据时返回 401 + WWW-Authenticate: Basic ...
  • 前端用 window.fetch / axios 等 XHR 调这些接口,没有自己设 Authorization
  • 常见误判:「浏览器第一次 401 会弹原生登录框,之后自动带凭据,所以现有 SPA 不用改」

症状

  • 地址栏打开受保护 URL(文档导航)时,确实会弹原生 Basic 框
  • 同一源的 SPA 里 fetch('/api/admin/summary') 永远 401,页面转圈或报错,没有登录框
  • curl 带 -u user:pass 正常;浏览器开发者工具里请求没有 Authorization

根因

WWW-Authenticate 触发的是文档导航(用户在地址栏进了一个受保护资源)的浏览器 UI。fetch / XHR 被设计成可编程的:401 只是给 JS 的响应,默认不弹窗、不重试、也不记住凭据。credentials: 'include' 也只影响 cookie,不会突然开始发 Basic。

所以「前端一行不改 + 纯 Basic」只对「整页都由浏览器自己请求」的站点成立,对 React admin 这种 fetch('/api/...') 不成立。

处理

不要把 Basic 当成 SPA 的登录方案。可选:

  1. 服务端登录页发 HttpOnly session cookie(同源 fetch 默认带 cookie)。Vite 若只代理 /api,登录入口也要挂在 /api/... 下,cookie 才能种到开发端口。
  2. 改前端,自己处理 401 / 自己带 Authorization(现有前端不允许改时走 1)。
  3. 仅本机调试可暂时关掉 API 守门;不要当生产默认。

Basic 仍可留给 curl、脚本、集成测试。

下次怎么认

看到「加了 Basic,前端不用改」+ 代码里是 fetch / axios,就默认会 401。用浏览器直接打开 API URL 能弹框,不能证明 SPA 能登录。

项目证据

rolefit-rs 管理端:源系统 /api/admin/* 是裸的;迁移补门时若只做 Basic,现有 job-admin/frontend 的 useApi.js 会整页失败。落地是 /login + /api/admin/login 会话 cookie,Basic 并行保留。


本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Web