diff --git a/README.md b/README.md index 2920de5..77d31e3 100644 --- a/README.md +++ b/README.md @@ -384,6 +384,11 @@ client_max_body_size 100m; # XXX WebSocket 语音听写需要较长连接时间。 proxy_read_timeout 3600s; proxy_send_timeout 3600s; + +# XXX SESSION_COOKIE_SECURE=true 时,后端必须能看到原始公网协议是 HTTPS。 +# XXX 如果登录接口 200 但没有 Set-Cookie,或 /api/auth/me 返回 401 未登录,补充这两行。 +proxy_set_header X-Forwarded-Proto https; +proxy_set_header X-Forwarded-Ssl on; ``` 公网验收顺序: @@ -396,7 +401,7 @@ proxy_send_timeout 3600s; 5. 浏览器控制台执行 window.isSecureContext,应返回 true;否则语音麦克风权限不会开放。 ``` -如果登录失败或刷新后掉登录,优先检查 `SESSION_SECRET` 是否稳定、`SESSION_COOKIE_SECURE=true` 时是否同时设置了 `TRUST_PROXY=true`,以及外层 NPM 是否把 `X-Forwarded-Proto: https` 传给后端链路。 +如果登录失败或刷新后掉登录,优先检查 `SESSION_SECRET` 是否稳定、`SESSION_COOKIE_SECURE=true` 时是否同时设置了 `TRUST_PROXY=true`,以及外层 NPM 是否把 `X-Forwarded-Proto: https` 传给后端链路。若 `POST /api/auth/login` 返回 200 但响应头没有 `Set-Cookie`,随后 `GET /api/auth/me` 返回 `401 未登录`,基本就是 HTTPS 协议头没有传到后端;按上面的 NPM Advanced 配置补充 `proxy_set_header X-Forwarded-Proto https;` 后重建/重启 Web/API。 如果只有语音识别失败,优先检查 NPM 的 `Websockets Support`、HTTPS 证书、浏览器麦克风权限、系统设置中的讯飞 APPID/APIKey/APISecret,以及后端容器是否能访问讯飞 `wss://iat-api.xfyun.cn/v2/iat`。 ## 当前限制 diff --git a/docs/deployment.md b/docs/deployment.md index 5ea4072..27d1844 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -133,6 +133,12 @@ Nginx Proxy Manager 代理 `your-domain.example` 时: - 开启 `Websockets Support`,否则 `/api/speech/iat` 语音 WebSocket 会失败。 - 绑定 SSL 证书并开启 `Force SSL`,否则浏览器不会开放公网麦克风权限。 - Advanced 中建议设置 `client_max_body_size 100m;`、`proxy_read_timeout 3600s;`、`proxy_send_timeout 3600s;`。 +- `SESSION_COOKIE_SECURE=true` 时,后端还必须收到 `X-Forwarded-Proto: https`。如果登录接口返回 200 但响应头没有 `Set-Cookie`,或刷新后 `/api/auth/me` 返回 `401 未登录`,在 Advanced 中补充: + +```nginx +proxy_set_header X-Forwarded-Proto https; +proxy_set_header X-Forwarded-Ssl on; +``` `# XXX` 公网正式访问只映射 `4002` 即可;不要把 Docker 自签名 HTTPS 演示入口 `4443` 映射到公网域名。 diff --git a/docs/docker.md b/docs/docker.md index 1bb08dd..f9a4de7 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -172,11 +172,26 @@ Nginx Proxy Manager 配置要点: - 开启 `Websockets Support`,保证 `/api/speech/iat` 语音听写 WebSocket 可升级。 - SSL 页签绑定证书并开启 `Force SSL`,保证浏览器开放麦克风权限。 - Advanced 中建议设置 `client_max_body_size 100m;`、`proxy_read_timeout 3600s;`、`proxy_send_timeout 3600s;`。 +- Advanced 中建议显式传递公网 HTTPS 协议,避免 `SESSION_COOKIE_SECURE=true` 时后端无法写入登录 Cookie: + +```nginx +proxy_set_header X-Forwarded-Proto https; +proxy_set_header X-Forwarded-Ssl on; +``` `# XXX` 公网正式访问只映射 `4002` 即可;不要把本机自签名 HTTPS 演示入口 `4443` 直接映射为公网域名入口。公网 HTTPS 应由 Nginx Proxy Manager 负责。 公网验收先访问 `https://your-domain.example/api/health`,再登录并测试报告保存、视频抽帧、AI 对话和语音听写。 +### 登录 Cookie 排查 + +如果公网登录后仍提示“未登录”,或系统设置等后端操作报 `401`: + +1. 在浏览器 Network 中查看 `POST /api/auth/login` 是否为 `200`。 +2. 检查该响应是否有 `Set-Cookie: surclaw.sid=...`。 +3. 如果登录为 `200` 但没有 `Set-Cookie`,说明后端没有确认当前请求是 HTTPS;确认 `SESSION_COOKIE_SECURE=true`、`TRUST_PROXY=true`,并在外层 Nginx Proxy Manager Advanced 中补充 `proxy_set_header X-Forwarded-Proto https;`。 +4. 修改代理或 `nginx.conf` 后需要重建/重启 `web`,修改 API 环境变量后需要重建/重启 `api`。 + ## 生产部署前必须修改 `docker-compose.yaml` 当前适合演示和院内试运行,生产前至少修改: diff --git a/nginx.conf b/nginx.conf index 2d34635..fe2b2b9 100644 --- a/nginx.conf +++ b/nginx.conf @@ -4,6 +4,8 @@ map $http_upgrade $connection_upgrade { } # XXX Preserve the public HTTPS scheme when an outer reverse proxy terminates TLS. +# XXX If the outer proxy does not send X-Forwarded-Proto, this falls back to this container's scheme. +# XXX For fixed public-HTTPS appliance packages, override the /api proxy header to "https". map $http_x_forwarded_proto $proxy_x_forwarded_proto { default $http_x_forwarded_proto; '' $scheme;