feat(browser): unify site credentials with browser profiles (BR-2)
- Inject the site account Cookie (manual + auto-login session, session wins)
into the camofox profile before the first tab opens; password accounts
without a session run refresh-login first; API Key sites are skipped.
- Cookie expired after injection -> credential.status=expired; cookie
accounts go to waiting/login_required ("log in once, applies site-wide").
- Write back site-domain cookies from the browser on handover, session close,
every 10 min of activity, and from refresh-login when the stored cookie is
invalid (verified before saving). user_info.cookieOrigin records
source=browser; source shown as manual/login/browser in the origin view.
- New camofox plugin umt-cookies (GET/POST /umt/sessions/:userId/cookies
under the access key); profile dir 0700/files 0600 in the desktop image.
- Single entry: sources-identity/service/credentials.ts.
- Real check: HHClub cookie injected into a fresh profile -> home page
logged in (logout link present), 5 cookies read back.
Requires rebuilding umt-browser-desktop (docker compose build camofox &&
docker compose up -d camofox) to take effect.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
901b01d1a1
commit
28974d1e1a
58 files changed
+2843
-1112
No files matched your search
@@ -340,3 +340,65 @@ docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt ./umt-root.cr
|
||||
- 一个桌面承载所有站点会话:持有 A 站租约的人在画面里能看到 / 操作切到前台的其它窗口;目前同一时刻一般只有一个会话窗口。
|
||||
- 真实输入法(Windows 微软拼音、macOS 日文)、Firefox / Safari 客户端、真实 PT 站点未测;容器内 fcitx5 只验证能启动,未验证组字。
|
||||
- 画面坐标与 camofox 截图坐标不同(桌面含 56 px 工具栏,Camoufox 伪装了 `screenX` / `outerHeight`),Agent 视觉操作继续用 camofox 截图。
|
||||
|
||||
## 9. 凭据统一:站点账号登录态 ⇄ 浏览器(BR-2)
|
||||
|
||||
一处管理凭据:站点账号里的 Cookie(手填,或账密自动登录得到的会话 Cookie)在打开浏览器会话时注入该站点 / 账号的 profile;
|
||||
人在浏览器里登录后,登录态读回站点账号,HTTP 抓取、RSS、快照下一次就用新的。截图模式与桌面模式是同一个 camofox 进程,共用。
|
||||
代码:`sources-identity/service/credentials.ts`(单一读写入口)、`modules/browser/service.ts`(`prepareCookies` / `syncCookies`)、
|
||||
`packages/adapters/src/browser/{cookies.ts,camofox/client.ts}`、camofox 插件 `docker/browser-desktop/root/opt/camofox/plugins/umt-cookies`。
|
||||
|
||||
### 9.1 注入做法
|
||||
|
||||
camofox 1.17.0 只有 `POST /sessions/:userId/cookies`(导入),而且要另一个口令 `CAMOFOX_API_KEY`;没有读取端点。
|
||||
所以桌面镜像带一个最小插件 **umt-cookies**(Dockerfile 把它加进 `camofox.config.json` 的插件清单),在访问凭据
|
||||
(`CAMOFOX_ACCESS_KEY`)之下提供:
|
||||
|
||||
| 端点 | 说明 |
|
||||
| --- | --- |
|
||||
| `POST /umt/sessions/{userId}/cookies` `{cookies}` | `context.addCookies`,并触发持久化插件立即落盘(与上游导入端点相同) |
|
||||
| `GET /umt/sessions/{userId}/cookies?urls=a,b` | 作用于这些地址的 Cookie:会话活着读 `context.cookies(urls)`,否则读 profile 落盘文件 |
|
||||
|
||||
适配器先走插件;插件不在(404)再试上游导入端点(`CAMOFOX_API_KEY` 与访问凭据相同时可用,只能写不能读);都不行 → 会话照常打开,
|
||||
`credential.status = unsupported` 并说明。profile 落盘在 `/root/.camofox/profiles/<sha256(userId) 前 32 位>/storage-state.json`
|
||||
(Playwright storageState:cookies + localStorage;sessionStorage 不保存,IndexedDB 缺省不保存),桌面镜像里目录 0700、文件 0600
|
||||
(`svc-camofox` 设 `umask 077`,`init-umt-desktop` 对旧卷 `chmod -R go-rwx`)。**改了镜像,需重建 `umt-browser-desktop` 后生效**
|
||||
(`docker compose build camofox && docker compose up -d camofox`);纯截图镜像 `camofox-browser:1.17.0` 不带插件,注入 / 回写都显示不支持。
|
||||
|
||||
打开会话(`POST /browser/sessions`、Agent `browser.navigate` 首次打开)时:
|
||||
|
||||
1. 匿名会话、API Key 类站点 / 账号(馒头:网页登录态与 API Key 无关)→ 不注入,`not_applicable`;
|
||||
2. 取账号 Cookie:用户填的 + 自动登录得到的会话 Cookie,同名以会话 Cookie 为准;账密账号还没有会话 Cookie → 先走一次 refresh-login;
|
||||
3. Cookie 头串转成站点主机的 host-only Cookie(路径 `/`,https 站点标 secure,期限 30 天——头串里没有期限,站点响应会按自己的期限覆盖),
|
||||
**在开第一个标签页之前**写进 profile,再导航;
|
||||
4. 注入了仍落在登录页 → `credential.status = expired`;Cookie 账号(没有密码可自动登录)转等待处理 `login_required`
|
||||
("登录已失效:接管后在画面里登录一次,交还后全站生效"),账密账号留给 Agent 用凭证注入登录。
|
||||
|
||||
会话详情 `credential`:`status`、`source`(`manual` 手填 / `login` 自动登录 / `browser` 浏览器回写)、`sourceAt`、`count`(个数,不含值)、
|
||||
`message`、`syncedAt`;原站视图顶栏显示"登录态:来源 · 时间"。
|
||||
|
||||
### 9.2 回写
|
||||
|
||||
| 时机 | 做法 |
|
||||
| --- | --- |
|
||||
| 人工接管交还 | 先按上游 `GET /tabs` 同步当前地址(桌面里的导航不经 API),不在登录页才读回 |
|
||||
| 关闭会话 | 关闭前读回一次(站点 / 浏览器服务停用导致的关闭不读) |
|
||||
| 定时 | 会话有动作时,距上次读回(或创建)满 10 分钟,后台读回一次 |
|
||||
| refresh-login 发现 Cookie 失效 | Cookie 账号:从浏览器 profile 读回(不要求会话开着,读落盘文件),与存的不同就拿它验证一次,有效才回写并标 active |
|
||||
|
||||
读回只取作用于站点主机的、未过期的 Cookie(统计 / CDN / 第三方域名一律丢弃),与存储比较(忽略顺序),有变化才写:
|
||||
Cookie 账号替换 `secret_ref`,账密账号替换(或新建)会话 Cookie;`site_account.user_info.cookieOrigin = {source: "browser", by: "browser", at}`,
|
||||
`expired` / `invalid` 的账号回到 `unknown`。来源判定:`cookieOrigin.at` 不早于 secret 最近写入(`rotated_at`,留 5 秒)才算浏览器回写,
|
||||
之后再手填或自动登录会让它变回 `manual` / `login`。
|
||||
|
||||
安全:Cookie 值只在服务端、secret 表与浏览器服务之间传;日志只记个数;会话详情 / 能力输出 / 模型上下文里没有值;快照遮蔽照旧(§3)。
|
||||
|
||||
### 9.3 真机核验(2026-09-29)
|
||||
|
||||
`scripts/browser-verify/cookie-real.ts`:临时容器 `camofox-browser:1.17.0` + 挂载 umt-cookies 插件(与用户栈同一网络、同一出口代理),
|
||||
读用户栈数据库里憨憨(hhanclub)账号的手填 Cookie(5 个),注入**全新** profile 后打开首页一次:HTTP 200、落在 `/` 不是登录页、
|
||||
页面有 `a[href*=logout.php]`(站点定义的登录成功标记)→ 已登录;插件读回 5 个、全部是 `hhanclub.net` 域名、包含注入的全部名字。
|
||||
对真实站点只有这一次导航,未截图。
|
||||
|
||||
没有核验的:桌面镜像重建后的端到端(接管 → 画面里登录 → 交还回写)只在 mock 上测过;其它三站;sessionStorage / IndexedDB 登录的站点
|
||||
(Cookie 注入不覆盖这类登录态)。站点账号列表里显示登录态来源待前端接 `userInfo.cookieOrigin`。
|
||||
Reference in new issue
Block a user