TRACIO 是一套客户端-服务端识别系统。客户端采集浏览器信号并将其发送到服务端,服务端计算出稳定的访客标识符、运行检测算法,并返回经过丰富化的结果。本节将逐一说明该流水线的各个阶段。
Browser TRACIO Cloud | | |-- Tracio.init({ publicKey }) ---------> | (init, no network) | | |-- tracio.getResult() ----------------> | | 1. Collect 300+ browser signals | | 2. Encrypt (XOR + deflate + B64) | | 3. POST to ingress endpoint | | | | |-- Decrypt & extract signals | |-- Compute visitor ID (MurmurHash3-128) | |-- Run bot detection (weighted scoring) | |-- Run smart signals (server-side enrichment) | |-- Run IP intelligence (VPN/proxy/Tor) | |-- Store visit event | | |<-- JSON response ------------------- | | visitorId, confidence, | | bot detection, smart signals | | | |-- Store visitor cookie (_vid_t) -----> | (365-day persistence)当 tracio.getResult() 被调用时,客户端会采集 300 多个不同的浏览器信号,这些信号按层级(tier)组织。采集过程采用多阶段流水线,并借助 Web Worker 和共享 iframe 来提升性能。
探针共提供 15 个类别下的 300+ 个信号:
| 类别 | 信号数 | 类别 | 信号数 |
|---|---|---|---|
| Tamper | 82 | Fonts | 15 |
| Navigator | 72 | Network | 15 |
| Bot | 32 | Persistence | 14 |
| Canvas | 26 | Intl | 13 |
| CSS | 19 | Audio | 12 |
| Privacy | 17 | Storage | 12 |
| Crypto | 16 | Behavioral | 5 |
| Display | 15 |
Canvas 除 2D 渲染外同样覆盖 WebGL 与 WebGPU;Tamper 是最大的类别,因为辨认一个被改动过的环境所需的探测,比读取一个未被改动的环境更多。
采集流水线分四个阶段运行,以尽量减少对主线程的阻塞:
阶段 1(立即执行):优先级高且采集速度快的信号(navigator 属性、屏幕、时区)。TURN 探测也在此处启动,因为它是并发运行的。
阶段 2(空闲回调):受益于空闲时段的同步信号(CSS 媒体查询、存储探测、Cookie 测试)。
阶段 3(异步):需要异步 API 或渲染的信号(Canvas、WebGL、音频指纹、字体检测、Emoji 渲染)。
Web Worker:在专用线程中进行隔离式信号采集(WASM 特性检测、doNotTrack)。
系统会一次性创建一个共享的隐藏 iframe,并由多个采集器复用(Emoji、MathML、系统颜色、字体、屏幕帧),从而避免为每个信号单独创建 iframe 带来的开销。
每个信号都遵循统一的结构:
interface Signal<T> { s: number // Status code v: T // Value (when successful)}状态码:
| 状态码 | 含义 |
|---|---|
0 | 成功 |
-1 | 不可用(属性为 undefined) |
-2 | 二次校验失败 |
-3 | 意外行为 |
-4 | 超时 |
-5 | 已禁用 |
-6 | 被 CSP 阻止 |
-7 | 安全错误 |
采集到的信号会先序列化为 JSON,然后在传输前进行加密和压缩:
JSON 序列化:所有信号值都被打包进一个以信号为键的 JSON 对象中,并附带元数据字段(c 表示 API 密钥,t 表示标签,lid 表示关联 ID)。
压缩:如果载荷超过 1024 字节,则使用 CompressionStream("deflate-raw") 进行压缩。
XOR 加密:载荷被封装进一个加密信封中:
Base64 编码:加密后的载荷经过 Base64url 编码,并作为 POST 请求体发送。
请求会发送到 ingress 端点,并携带表示客户端版本和 API 密钥的查询参数。请求包含 CORS 凭据,以便发送第一方 Cookie。
服务端接收加密后的载荷,并通过多个子系统对其进行处理:
服务端解码 XOR 信封,必要时进行解压,并解析 JSON 信号数据。每个信号的状态码和值都会被提取并校验。
访客 ID 采用**分层哈希(tiered hashing)**方法计算(V3):
Tier 1 (Frozen): 20 base62 characters - Stable hardware signals that rarely change - Canvas, WebGL renderer, audio fingerprint, fonts - Provides long-term visitor identity
Tier 2 (Semi-stable): 10 base62 characters - Signals that change with browser updates - User-Agent data, Client Hints, plugins - Extensible without breaking Tier 1
Tier 3 (Volatile): 10 base62 characters - Signals that change frequently - Screen resolution, timezone, language - Used for confidence scoring, not identity每个层级提取其指定的信号,构建一个规范化字符串,并使用 MurmurHash3-x64-128 对其进行哈希。三个层级的哈希值被拼接起来,并以 base62 编码,从而生成最终的访客 ID。
置信度得分(0.0 到 1.0)表示系统对该访客已被正确识别的确信程度:
_vid_t Cookie 与某个已知访客匹配,则置信度为最大值。机器人检测引擎会运行多个检测器,并把它们的加权输出汇总为一个机器人得分;单独一个硬失败(hard-fail)信号本身即可判定为机器人。对外公开的 bot.score 是 0..100 的取值范围,判定结果则以 bot.result 的形式返回。确切阈值不予公布:能被读到的阈值,就是能被人调校规避的阈值。参与评分的检测器包括:
插桩(Frida)、root/越狱以及克隆应用这几类检测器在平台中确实存在,但它们的输入槽位仅面向原生端——浏览器探针并不采集这些数据,因此它们不会参与 Web 侧的判定。Web 上完全生效的能力,参见 机器人检测。
服务端丰富化信号由原始信号数据和 IP 情报计算得出。这些信号包括 VPN/代理/Tor 检测、IP 地理定位、浏览器篡改分析以及可疑度评分。
IP 情报子系统提供:
服务端返回一个 JSON 响应,其中包含:
{ "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "bot": { "detected": false, "confidence": 2, "reasons": [] }}这就是 tracio.getResult() 在浏览器中解析出的结果。完整且经过丰富化的事件——包括规范化的 bot_result(human / bot / uncertain)、地理定位以及智能信号——通过 webhooks 在服务端交付,可通过 Data API 读取,并在仪表盘中呈现。
客户端会将访客令牌同时存储在第一方 Cookie(有效期 365 天,SameSite=Lax)和 localStorage 中,以实现跨会话的持久化。
| 步骤 | 位置 | 描述 |
|---|---|---|
| 1 | 浏览器 | 初始化探针,创建共享 iframe |
| 2 | 浏览器 | 采集 300 多个信号(并行、多阶段) |
| 3 | 浏览器 | 加密并压缩载荷 |
| 4 | 网络 | POST 到服务端 |
| 5 | 服务端 | 解密、提取信号、计算访客 ID |
| 6 | 服务端 | 运行机器人检测和智能信号 |
| 7 | 服务端 | 构建响应 |
| 8 | 网络 | 返回 JSON 响应 |
| 9 | 浏览器 | 存储访客 Cookie |
总往返时间:以毫秒计。其中占大头的是信号采集,网络往返与服务端处理只占较小部分;具体耗时取决于访客的设备与网络连接。这一切都不会阻塞页面渲染:探针以异步方式加载,每一项可能变慢的检查都受自身超时限制。