Windows Hub 配对 Device Token Mismatch 问题记录
现象
Windows Hub(OpenClaw Companion / OpenClaw Windows Tray)连接本地 Gateway 时反复报错:
unauthorized: device token mismatch (rotate/reissue device token)
AUTH_DEVICE_TOKEN_MISMATCH
配对流程能走通(设备可添加到 paired.json),但重连时始终 token 不匹配。
根因
认证协议设计冲突
Hub 和 Gateway 使用两套独立的认证机制,但 Gateway 对它们做了重复校验:
| 机制 | Hub 侧 | Gateway 侧 |
|---|---|---|
| Ed25519 签名 | 用私钥签名 nonce,证明持有私钥 | 用存储的公钥验证签名,确认设备身份 |
| Bearer Token | 自己算一个 DeviceToken 存本地 |
在 paired.json 里存一个 token,重连时比对 |
Hub 连接时同时发送:
- Ed25519 签名结果(
sigToken)—— 用私钥签名 challenge nonce - DeviceToken(
auth: { "deviceToken": "..." })—— 自己预先算好的字符串
Gateway 做两次检查:
- 签名验证 ✅ 通过 → 公钥对得上,确实是这台设备
- Token 比对 ❌ 不通过 → Hub 发来的跟
paired.json里存的不一样
签名已经证明身份了,Token 比对是重复且多余的检查。 但 Gateway 对支持 Ed25519 签名的客户端和不支持签名的客户端(如 WebChat)共用了一套 token 验证逻辑,导致能做签名的 Hub 反而被卡住。
Token 来源不同
设备身份文件 device-key-ed25519.json 内容:
{
"DeviceId": "cf87c3f5...",
"DeviceToken": "cJKaDPC6c9DonmrgYLcZvfzyL148QfK0uklsnD8rYs8", ← Hub 自己算的
"NodeDeviceToken": null,
"PrivateKeyBase64": "...",
"PublicKeyBase64": "..."
}
Gateway 侧 paired.json 内容:
{
"tokens": {
"operator": {
"token": "i2rzlakl8PMTzI2LXES8XZV_62k4G60run_0nCGZzkE", ← Gateway 签发的
...
},
"node": {
"token": "UVGUO76VzIffDQ1FI5jYMQPKoJm62SuAwZH6rTcFWsk", ← Gateway 签发的
...
}
}
}
两个 token 完全无关,各自独立生成。
批准流程加剧问题
每次 openclaw devices approve 批准配对时,Gateway 签发一个新的 token。但这个新 token 与 Hub 自己算的那个不相关,Hub 也不会去用。Hub 下次重连仍然带着自己原先算好的 token,Gateway 一比对又 mismatch。
排查过程
1. 清理垃圾数据
初期发现 devices/paired.json 里堆积了大量重复/废弃的设备记录:
- 多个同名 "Windows Node (DESKTOP)"
- 多个同名 "OpenClaw Windows Tray"
- 多数 token 已被吊销
清理后只剩正常设备,但问题未解决。
2. 陷入死循环
反复尝试:
- 删除设备 → 重启 Gateway → Hub 重连 → 发起新配对 → 批准 → mismatch
- 删除
%APPDATA%→ 重装 Hub → 同上
均无效,因为每次批准后 Gateway 签发新 token,Hub 仍用自己的旧 token。
3. 从日志找到突破口
查看 Hub 日志 %LOCALAPPDATA%\OpenClawTray\openclaw-tray.log:
Loaded Ed25519 device identity: cf87c3f5d81e2ae2...
hasDeviceToken=True
auth: {"deviceToken":"[REDACTED]"}
→ AUTH_DEVICE_TOKEN_MISMATCH
4. 定位身份文件
发现设备身份存储在:
%APPDATA%\OpenClawTray\gateways\<gateway-id>\device-key-ed25519.json
该文件包含 Hub 自算的 DeviceToken。
5. 最终修复
手动将 paired.json 里该设备的 operator.token 和 node.token 改为 Hub 自算的 DeviceToken,两边一致后重连成功。
修复方法
# 1. 读取 Hub 的 DeviceToken
cat %APPDATA%\OpenClawTray\gateways\*\device-key-ed25519.json
# 2. 将 Gateway 侧对应设备的 token 改为相同值
# 编辑 ~/.openclaw/devices/paired.json
# 找到该设备的 tokens.operator.token 和 tokens.node.token
# 3. 重启 Gateway
openclaw gateway restart
建议
短期
Gateway 对已通过 Ed25519 签名验证的连接应跳过 token 比对,直接信任。
长期
Hub 和 Gateway 的认证协议应统一:
- 统一使用 Ed25519 签名验证(Hub 已支持)
- 对不支持签名的客户端(WebChat 等)保留 bearer token 路径
- 两种路径互不干扰,不做交叉校验
相关文件
| 文件 | 用途 |
|---|---|
~/.openclaw/devices/paired.json |
Gateway 侧已配对设备及 token |
~/.openclaw/nodes/paired.json |
Gateway 侧已配对节点能力注册 |
%APPDATA%\OpenClawTray\gateways\<id>\device-key-ed25519.json |
Hub 侧 Ed25519 密钥对及自算 token |
%LOCALAPPDATA%\OpenClawTray\openclaw-tray.log |
Hub 运行日志 |
%APPDATA%\OpenClawTray\settings.json |
Hub 配置(含 Node 开关) |
%APPDATA%\OpenClawTray\gateways.json |
Hub 已保存的 Gateway 连接信息 |
评论 ()