codex-console安全基线教程:API与WebSocket统一鉴权与默认口令强制改密完整指南
【免费下载链接】codex-consolecodex-console 是一个集成化控制台项目,支持任务管理、批量处理、数据导出、自动上传、日志查看与打包支持。项目地址: https://gitcode.com/gh_mirrors/co/codex-console
📌 本文带你快速掌握codex-console的安全基线设计:这个集成化控制台(任务管理、批量处理、数据导出、自动上传、日志查看)如何为API 与 WebSocket 提供统一鉴权,以及默认口令强制改密流程如何防止未授权访问。新手按文中步骤走一遍,即可把部署后的控制台调到"安全可用"状态。
为什么控制台需要安全基线?
codex-console 的 Web UI 默认监听0.0.0.0:8000(见 src/config/settings.py 中的webui_host/webui_port配置)。端口一旦对局域网甚至公网开放,以下风险就会真实存在:
- 默认访问密码
admin123人人皆知,等同于不设防; - 默认密钥
your-secret-key-change-in-production会被用于生成登录 Cookie 令牌,泄露后登录态可被伪造; - WebSocket 频道(任务日志、批量状态推送)如果绕过鉴权,日志内容就能被未登录者"偷听"。
项目的应对思路很直接:一个鉴权模块管住所有入口,一套默认配置检测管住"出厂裸奔"状态。
统一鉴权核心:一个模块守住 API 与 WebSocket
所有鉴权逻辑集中在 src/web/auth.py 一个文件里,这也是你排查"为什么 401/423/4403"时唯一需要看的地方。
登录令牌:HMAC-SHA256 派生,而非明文 Cookie
登录成功后,服务端不会把密码本身写进 Cookie,而是用访问密码 + 密钥通过 HMAC-SHA256 派生出一段不可逆的令牌(build_auth_token):
Cookie 值 =
HMAC-SHA256(secret_key, access_password)
校验时用secrets.compare_digest做恒定时间比较(is_request_authenticated),避免时序侧信道攻击。
API 鉴权:路由级依赖项,一处生效、全局覆盖
在 src/web/app.py 中,整个/api前缀的路由器挂载了统一依赖:
app.include_router(api_router, prefix="/api", dependencies=[Depends(require_api_auth)])也就是说 src/web/routes/ 下的 accounts、tasks、registration、settings 等全部 REST 接口共享同一道闸门。require_api_auth(src/web/auth.py#L72-L83)的行为分两档:
| 场景 | 响应 | 含义 |
|---|---|---|
| 仍在默认口令/默认密钥 | 423+password_change_required | 先访问/setup-password改密 |
| 未登录或 Cookie 失效 | 401+ "未登录或登录已失效" | 重新走登录页 |
对应的回归测试见 tests/test_security_and_task_routes.py,它直接断言/api/accounts路由必须挂载require_api_auth依赖项——防止后续开发时"悄悄拆掉"鉴权。
WebSocket 鉴权:同样的令牌,自定义关闭码
WebSocket 无法使用 HTTP 状态码,项目用关闭码表达同样的语义(websocket_auth_failure):
4401 unauthorized:令牌不匹配,连接在accept之前被直接拒绝;4403 password_change_required:默认口令未改,任何实时频道都不开放。
两条实时频道 task_websocket(任务日志)与 batch_websocket(批量状态)都在建立连接的第一时间调用 is_websocket_authenticated 校验 Cookie,校验不过就不accept,未授权者拿不到任何一条历史日志。
默认口令强制改密流程:302 重定向的"安全闸门"
触发条件:什么时候会强制改密?
is_default_security_config_active 定义了"出厂裸奔"状态,满足任意一条即命中:
- 访问密码为空;
- 访问密码仍为
admin123; - 密钥为空;
- 密钥仍为默认占位值。
服务启动时若命中该状态,日志会明确提示Default security config detected, visit /setup-password(src/web/app.py#L116-L117)。
改密流程逐步拆解
🔐 完整流程对应 templates/setup_password.html 页面与 /setup-password 接口:
- 强制跳转:默认口令状态下,访问任意页面(
/、/accounts、/settings等)都会被_guard_page_request以302重定向到/setup-password; - 验证旧密码:表单需填写当前密码,错误则返回
Current password is incorrect; - 强度校验:新密码至少 8 位、两次输入必须一致、禁止仍使用
admin123; - 一键换血:校验通过后,除了写入新密码,还会用
secrets.token_urlsafe(48)随机重生成整个密钥(src/web/app.py#L299-L302),旧令牌全部作废,同时删除旧 Cookie 并跳转登录页。
💡 关键点:改密不只是"换个口令",密钥的同步重生成让所有已派生的登录令牌一次性失效,天然完成一次"全员重登录"。
登录、Cookie 与登出:闭环细节
- 登录:/login 用
secrets.compare_digest校验密码,成功后签发 Cookiewebui_auth,并设置HttpOnly+SameSite=Lax,前端 JS 无法读取,抵御 XSS 窃取 Cookie; - 登出:/logout 仅删除 Cookie——由于令牌是密码+密钥的纯函数派生,删掉 Cookie 即彻底失效,无需维护服务端会话表;
- 调试文档收口:
/api/docs、/api/redoc仅在debug=True时开启(src/web/app.py#L158-L159),生产环境建议保持关闭。
敏感配置清单:密钥类字段全部走 SecretStr
改完口令后,建议顺手检查数据库中其他"出厂即敏感"的字段。在 src/config/settings.py 中,所有标记is_secret=True的配置项都会以 Pydantic 的SecretStr类型加载(打印日志时自动打码为***):
webui_access_password/webui_secret_key:登录与令牌核心;security.encryption_key:数据库敏感数据加密密钥,默认值同样是占位符,生产环境必须更换;proxy_password、yyds_mail.api_key、tm.api_key、cpa.api_token等第三方凭据。
项目内置的动态代理凭据即属此类(proxy_dynamic_api_key)。项目文档中代理资源的示例横幅如下,实际部署时请替换为你自己的代理与密钥:
新手自检清单 ✅
部署 codex-console 后,用这 6 条逐项过一遍:
- 浏览器访问任意页面,是否被重定向到
/setup-password?改密完成后不再出现; - 用旧密码重新登录,应提示密码错误(旧令牌已作废);
- 未登录直接请求
/api/accounts,应返回401而非数据; - 用
wscat等工具直连ws://host:8000/api/ws/task/xxx(不带 Cookie),连接应被以4401关闭; - 检查
debug配置为false,确认/api/docs不可访问; - 数据库中的
security.encryption_key已替换为自定义值。
小结
codex-console 的安全基线可以概括为三句话:src/web/auth.py一个模块统一鉴权 API 与 WebSocket;HMAC 派生令牌 + 恒定时间比较 + HttpOnly Cookie保证登录态不可伪造、不可窃取;默认口令强制改密 + 密钥自动重生成保证服务一上线就不"裸奔"。按本文清单走完一遍,你的控制台就具备了可对外共享的最小安全配置。
【免费下载链接】codex-consolecodex-console 是一个集成化控制台项目,支持任务管理、批量处理、数据导出、自动上传、日志查看与打包支持。项目地址: https://gitcode.com/gh_mirrors/co/codex-console
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考