
DeviceToken 每次都变还只有一小时HarmonyOS 7 设备状态怎么做成幂等状态机客户端连续调用 getDeviceToken拿到的字符串不同并不代表设备换了。官方文档明确说明 DeviceToken 每次调用都会变化有效期为一小时服务端提供查询、设置和删除设备状态的接口每个设备与应用组合可保存两位状态。把 token 当数据库主键刷新一次就会制造一条“新设备”。正确做法是把它当短期访问凭证由服务端把状态变化做成幂等操作。先把官方边界和项目策略分开关注点官方边界或工程判断常见错误DeviceToken每次调用变化有效期一小时缓存成永久设备标识设备状态每设备每应用两位含义由业务定义把位值写死在页面调用位置客户端取 token服务端查询或更新在客户端保存管理凭据上表左侧是接口事实中间同时包含官方边界与明确标注的工程判断右侧是最容易造成线上误判的写法。接入前先确认系统能力与版本再把调用放到统一服务里不要让每个页面分别复制一套安全逻辑。案例一重复提交不会把状态来回翻转把“设置风险状态”设计成目标值写入而不是 toggle。网络超时后客户端可以用同一个业务请求号重试服务端发现请求已处理就返回原结果。两位状态可以示例性定义为 trusted 与 needsReview但这只是项目约定不是系统固定语义。type DeviceBits { trusted: 0|1; needsReview: 0|1 }; type Command { requestId: string; next: DeviceBits }; function applyCommand(current: DeviceBits, command: Command, processed: Setstring): DeviceBits { if (processed.has(command.requestId)) return current; processed.add(command.requestId); return { ...command.next }; } const done new Setstring(); let state applyCommand({ trusted: 0, needsReview: 0 }, { requestId: r-7, next: { trusted: 1, needsReview: 0 } }, done); state applyCommand(state, { requestId: r-7, next: { trusted: 0, needsReview: 1 } }, done); if (state.trusted ! 1 || state.needsReview ! 0) throw new Error(重复请求破坏了幂等性);第一段代码只验证外围决策模型。它不替代 Device Security Kit 的真实调用也不包含生产密码学实现价值在于让边界条件、重试和降级可以重复测试。案例二过期 token 触发刷新而不是误判新设备服务端返回凭证过期时客户端重新获取一次 token 并重放查询只有刷新仍失败才进入可恢复降级。为防止循环刷新次数必须有限制。业务请求号保持不变token 变化也不会制造重复状态写入。type Attempt { tokenAgeMinutes: number; refreshCount: number }; function nextTokenAction(a: Attempt): use|refresh|fallback { if (a.tokenAgeMinutes 55) return use; if (a.refreshCount 1) return refresh; return fallback; } if (nextTokenAction({ tokenAgeMinutes: 61, refreshCount: 0 }) ! refresh) throw new Error(过期凭证未刷新); if (nextTokenAction({ tokenAgeMinutes: 61, refreshCount: 1 }) ! fallback) throw new Error(刷新循环未截断);第二个案例覆盖另一类失败路径。接入系统接口时还要验证不支持、权限拒绝、网络超时、频控、前后台切换与进程恢复不能只跑一次成功流程。为什么选择这种做法永久缓存 token 会制造身份漂移失败就清空状态会扩大网络抖动影响幂等目标值加有限重试更稳。设备状态只适合承载很小的服务端标记复杂画像仍应存放在自己的受控后端。真正值得复用的不是某个页面回调而是“输入事实 - 安全信号 - 分级决策 - 可恢复反馈”这条链。页面只消费结果服务层负责版本、频控、超时和脱敏服务端负责挑战、验签与审计。这类能力为什么容易接错安全接口最危险的误区是把一次返回值直接翻译成“允许”或“拒绝”。真实链路至少包含能力是否支持、调用是否成功、结果是否可信、结果是否仍在有效期、业务能否降级五层。任何一层缺失都不应该把用户永久挡在门外。接口给的是安全信号业务需要的是可解释、可恢复的决策。建议把系统能力放在薄适配层里业务层只接收普通对象。这样既能在宿主环境验证状态转换也能在更换 SDK 或设备能力时集中修改。日志只保留请求编号、耗时、错误类别和脱敏后的策略结果不记录 token、nonce、完整 JWS、网址参数、设备标识或用户内容。怎样验证哪些结论还不能提前说下面代码中的纯 TypeScript 决策函数可以在宿主环境运行断言用来证明分支、位掩码和状态转换没有自相矛盾。涉及 Device Security Kit、权限、传感器、网络、证书链和系统窗口的片段仍需 API 26 SDK 编译并在支持相应能力的 HarmonyOS 7 设备上验证。当前本地环境只能验证外围模型不能把它写成“已经完成 API 26 编译”或“真机实测通过”。正式验收至少记录 DevEco Studio 与 SDK 版本、设备系统版本、能力探测结果、正常与失败路径、频控表现、前后台恢复和降级提示。服务端验签还应保存证书链版本、验签失败类别和时钟偏差但绝不落原始敏感凭证。封装与复用建议推荐统一输出四类结果可信并放行、需要二次确认、暂时不可用可重试、不支持而降级。页面只负责展示和触发不直接解析 JWS、位掩码或错误码。服务端策略要有版本号客户端上报能力版本和匿名请求编号方便灰度回滚。这样同一套安全边界可以复用到登录、支付、内容发布和企业管控而不会把具体页面写死在系统接口里。发布前自查文章使用的是 2026 年 9 月更新的官方资料并明确适用版本与设备范围。两个案例覆盖不同失败条件不是同一段代码改变量名。频控、有效期、权限和设备支持范围均有出处项目策略与官方规定明确区分。没有把单一安全信号作为唯一封禁依据也没有把未运行的设备结果写成实测。日志、埋点、截图和示例数据不包含真实 token、nonce、JWS、URL 查询参数或设备标识。官方资料设备状态检测开发指导Device Security Kit 开发概述