Files
MediaCrawler/mac-agent-os-main/03_knowledge/99_system/architecture/login-system-tech-map.md
T
butubb 2112c1a870
Deploy VitePress site to Pages / build (push) Canceled after 0s
Deploy VitePress site to Pages / Deploy (push) Canceled after 0s
feat(monitor): 抖音 Web 接口客户端 —— 绕开爬虫子进程,直接发 HTTP
移植自 mac-agent-os 的 mediacrawler_adapter:不起子进程、不开页面,用浏览器里那份
登录态直接调抖音 Web 接口。产物键名照抄 store/douyin,所以 ingest 那条链路一个字不用改。

**目前能用的(真环境实测,非推断)**:

    profile/other : 200, 7075 字节  —— 博主主页指标(粉丝/获赞/作品数/昵称)
    aweme/detail  : 200, 45425 字节 —— 单条作品详情(含点赞/评论/收藏/分享)

**目前不能用的:作品列表 `aweme/post`。** 两个互相独立的原因:
  1. 这个接口被抖音单独升级成了真校验:不带 x-tt-argus 回 403「Uifid Not Found」,
     带上 dummy 值回 200 + **空 body**。也就是说「头在不在」骗得过,「真校验」过不了。
     同一套头打 profile/other 和 aweme/detail 都是通的 —— 抖音是挑着接口加保护的,
     挑中的恰好是「批量拉作品列表」这个最敏感的动作。
  2. 改走页面截获也不行:CDP 浏览器打开博主主页会落到「验证码中间页」(当天大量探测的
     代价,过几小时要重测)。

  所以现在的边界是:**已知作品的指标刷新能做,自动发现新作品做不了**。

**排查中控住变量后得到的两条事实**(都写进注释了):
  · `Accept` / `Accept-Language` / `Referer` 才是主页接口能返回真数据的原因 —— 只有
    UA+client hints+Cookie 时是 200 但仅 121 字节的空壳,补上这三个头变 7074 字节。
    (我先前猜的 sec-ch-ua 不是关键。)
  · 因此 UA 与 client hints 必须**成套地取自同一个浏览器**,所以 BrowserIdentity 一次
    从 CDP 取齐 cookie + UA + hints,而不是各自写死。

「200 + 空 body 必须当场报错」也是刻意写死的:放过去它会在下游变成「这个博主没作品」,
把一次失败伪装成一条正常结果 —— 爬虫那条路正是这么栽的,还被翻译成「账号被封」。

测试 +11:cookie 解析、请求头成套性(含 uifid 缺失/回退)、产物键名与 store 对齐、
以及 _get 的三条失败路径(空 body / 403 带网关原话 / 正常返回)。
2026-10-10 17:12:25 +08:00

217 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: concept
domain: system
nature: architecture
tags: [agentos, v3.0, matrix, login, auth, sms]
status: draft
created: 2026-06-16
updated: 2026-06-16
version: 1.0.0
---
# AgentOS 联邦登录系统 — 技术图谱 v1.0
> 目标: 全自动跨平台登录,智能匹配登录方式,零人工介入
---
## 一、现有代码结构总览
```
scripts/
├── login_identity.py # 手动登录(旧,等待用户按Enter)
├── auth_manager.py # 登录态检测原子模块 ✅
├── cdp_connector.py # 浏览器连接器(Camoufox持久化/CDP)✅
│
├── matrix_modules/account/
│ ├── douyin_login.py # 抖音自动登录(含SMS)✅ 核心
│ ├── xiaohongshu_login.py # 小红书自动登录 ❌ 缺失
│ ├── sms_login.py # SMS验证码原子操作 ✅ 核心
│ └── sms/
│ ├── __init__.py # 统一导出
│ ├── base.py # SMSHandler 抽象基类
│ └── api.py # ApiSMSHandler API轮询 ✅ 核心
│
├── dashboard/plugins/
│ └── sms_proxy_api.py # Dashboard登录API(调的是旧脚本)⚠️
│
└── archive/
├── scan_login.py # 扫码登录(归档)📦
└── test_sms_login.py # 短信登录测试(归档)📦
```
## 二、平台登录流程对比
### 2.1 抖音登录(已有 douyin_login.py)
```
前置检测:
1. 读取 accounts.yaml → 手机号
2. 创建/确认身份目录
3. 启动 Camoufox 持久化浏览器
执行流程:
1. 导航 https://www.douyin.com/
2. 等待6秒 → 检测登录面板 #login-panel-new
3. 如果已经登录(检测 data-e2e=user-avatar)→ 跳过
4. 没检测到面板 → 等待15秒让用户手动点"登录"
5. 检测到面板 → 调用 sms_login 流程
SMS登录子流程 (sms_login.py):
Step 1: 点"一键登录"按钮
Step 2: 等待验证码输入框出现
Step 3: ApiSMSHandler 轮询获取验证码(最多3次,超时重发)
Step 4: 填入验证码(JS设置value+dispatchEvent)
Step 5: 点确认(DOM点击 → 系统级鼠标兜底)
Step 6: 验证登录态(面板消失+有头像)
后置处理:
- 写操作日志 login_log.jsonl
- 采集用户资料 ProfileScraper
- 浏览器保持打开
```
### 2.2 小红书登录(缺失)
```
当前状态:
- 无独立入口脚本
- sms_login.py 的原子操作可复用(点击按钮/填验证码/点确认)
- 登录面板检测、一键登录、URL导航需要适配
差异点:
- 登录URL不同: https://www.xiaohongshu.com/explore
- 登录面板CSS选择器不同
- "一键登录"按钮文本可能不同
- 登录态Cookie名不同: a1 / web_session
```
### 2.3 扫码登录(归档)
```
archive/scan_login.py 已实现:
- 生成二维码
- 检测扫码结果
- 确认登录
适用场景: 桌面端抖音扫码登录
```
## 三、登录态检测体系
### 3.1 四维状态检测(当前 sms_proxy_api.py)
| 维度 | 检测方式 | 判断依据 |
|:-----|:---------|:---------|
| has_identity | 文件夹存在性 | `identities/{name}/user_data/` 是否存在 |
| has_cookie | Firefox cookies.sqlite | `SELECT count(*) FROM moz_cookies WHERE name LIKE '%session%'` |
| has_profile | 文件存在性 | `user_data/profiles.yaml` 是否存在 |
| has_registry | 注册表存在性 | 账号是否在 accounts.yaml 注册 |
### 3.2 Cookie 级检测(auth_manager.py)
| 平台 | 关键Cookie | 检测方式 |
|:-----|:-----------|:---------|
| 抖音 | `sessionid`, `sid_guard` | Cookie名匹配 |
| 小红书 | `a1`, `web_session` | Cookie名匹配 |
### 3.3 DOM 级检测(auth_manager.py)
| 平台 | 选择器 | 说明 |
|:-----|:-------|:-----|
| 抖音 | `[data-e2e='user-avatar']` | 主指示器 |
| 抖音 | `[data-e2e='user-detail']` | 备用 |
| 小红书 | `.user-avatar` | 头像元素 |
| 小红书 | `.reds-count` | 计数元素 |
### 3.4 综合检测逻辑 (get_login_status)
```
Cookie 检测ok 且 DOM 检测ok → method='both'
Cookie 检测ok → method='cookie'
DOM 检测ok → method='dom'
兜底: Cookie数量 > 30 → 判定已登录
```
## 四、需要补充的环节
### P0: Dashboard 调正确脚本
```
当前: /api/matrix/accounts/{id}/login → login_identity.py(手动)
预期: 根据 platform 自动路由:
douyin → douyin_login.py(全自动)
xiaohongshu → xiaohongshu_login.py(待创建)
```
### P0: 小红书入口脚本 (xiaohongshu_login.py)
```
复用 douyin_login.py 框架 + sms_login.py,仅修改:
- 平台URL → xiaohongshu.com/explore
- 登录面板选择器 → 小红书专用
- 一键登录按钮文本 → 适配小红书
- Cookie规则 → auth_manager 已有
```
### P1: 智能匹配引擎
```
根据账号信息自动选择登录方式:
1. 已登录 → 跳过(检测 has_cookie + 验证过期)
2. 有身份无Cookie → 按平台执行自动登录
3. 首次登录 → 创建身份 → 自动登录
4. 短信登录 → 自动触发短信 → 轮询获取 → 自动填入
5. 扫码兜底 → 检测平台是否支持扫码
```
### P1: 过期session检测
```
方法: 在登录页检测"已登录"状态后,导航到个人中心
检查是否可加载用户信息(不发敏感请求)
如果跳转到登录页 → session过期
```
### P2: 跨机路由
```
远程机器登录:
Dashboard → fire-and-forget 发送命令
远程机器 → 执行 douyin_login.py
完成后 → 更新本地 has_cookie 状态
```
## 五、当前系统完整调用链
```
Dashboard 🔑 点击
↓
POST /api/matrix/accounts/{id}/login
↓
sms_proxy_api.py: api_account_login()
↓
subprocess.Popen([agent-os python, -m, mc, account, login, {id}])
↓ (当前链路)
mc/cli.py: cmd_login()
↓
subprocess.Popen([sys.executable, login_identity.py, {id}, --platform {p}])
↓
login_identity.py → 开Camoufox → 等Enter → 检测Cookie → 退出
⚠️ 需要人按Enter,不是全自动
↓ (目标链路)
mc/cli.py: 新增路由 → 检测platform
↓ douyin
douyin_login.py → 开Camoufox → 自动点一键登录 → 自动收短信 → 自动填 → 自动确认 → 自动验证
↓ xiaohongshu (待创建)
xiaohongshu_login.py → 同上逻辑
```
## 六、设计原则(不改原有代码,只加新功能)
1. **原有脚本不动** — `login_identity.py` 保留,通过新入口分流
2. **新增平台脚本** — 按 `douyin_login.py` 模板创建 `xiaohongshu_login.py`
3. **智能分流** — `mc account login` 检测 platform 自动路由
4. **逐步替换** — 新流程跑通后再切换 Dashboard 默认调用
5. **兜底机制** — 自动流程失败后提示用户手动操作
---
*版本: 1.0.0-draft | 2026-06-16*