先看结论与判断条件
- 移动端作为公共客户端无法安全存储静态密钥,必须依赖短期范围令牌机制。
- aud 与 scope 声明是防止令牌滥用到非目标 AI API 服务的基础防线。
- 令牌有效期应根据风险评估设定,RFC 9068 未规定具体时长数值。
- DPoP 将令牌绑定到客户端密钥可显著降低重放风险,但无法取代短有效期。
- 平台完整性信号仅作为风险参考,不能替代服务端最终授权决策。
- 服务端校验应综合 exp、aud、scope、DPoP 证明及设备信号,资料未证明缺少其中任一项必然导致授权失败。
- 工程判断:可采用刷新令牌轮换来缩短长期凭证的可用窗口;本文所引资料未把轮换规定为所有移动 AI API 的强制方案,需结合授权服务验证。
- 代码示例仅用于演示声明校验逻辑,生产环境必须验证签名且不可省略。
移动端调用 AI API 的权限模型困境
原生 App 属于公共客户端,不能依赖嵌入包内的客户端秘密,这是 RFC 8252 给出的基本边界。静态 AI API 密钥一旦随应用分发,就可能从安装包或运行进程中被取得并在其他环境调用。客户端因此只持有服务端按会话签发的访问令牌,长期供应商凭据留在服务端。
标准的应对方式是服务端签发短期访问令牌,客户端在取得令牌后用于 API 请求。但许多早期接入方案签发的是长期有效甚至是永不过期的令牌,一旦被中间人攻击或客户端日志泄露,攻击窗口极大,配合粗粒度的 scope 会让整个 AI 资源暴露。对于每个请求可能消耗大量算力的推理接口,单次滥用即可产生高额账单,且模型输出的数据可能包含用户隐私,致使安全事件的法律后果更加严重。缩短有效期并限定操作范围,是降低这类风险的核心手段,但这需要服务端具备完善的令牌生命周期管理能力。
JWT 访问令牌可以携带签发者、受众、过期时间和 scope,资源服务器据此执行结构化校验;RFC 9068 给出了这类令牌的字段约束。对重放风险较高的调用,可再用 DPoP 把令牌与客户端密钥关联。设备环境信号只提供额外上下文,不会让被完全控制的客户端变成可信终端。
工程实践中,开发者常误以为只要使用了 HTTPS 就能保证令牌安全,忽略了客户端内部的泄露风险。实际上,一旦设备被攻破,内存中的令牌依然可能被提取。因此,令牌的生命周期必须足够短,使得攻击者在提取令牌后,尚未完成攻击准备令牌就已失效。同时,令牌的用途必须被严格限制,即使被窃取,也无法用于执行高权限操作或访问其他微服务。这种纵深防御思路要求架构师在设计之初就明确各组件的信任边界和失效模式。
| 方案 | 安全性 | 凭证泄露窗口 | 实施复杂度 |
|---|---|---|---|
| 静态 API 密钥硬编码 | 极低,一旦提取则完全暴露 | 无限期 | 低,无需签发流程 |
| 长期刷新令牌 + 短期访问令牌 | 中,刷新令牌可能被窃取 | 访问令牌窗口短,刷新令牌窗口长 | 中,需要令牌交换流程 |
| 短期范围 JWT+DPoP 绑定 | 高,令牌绑定到客户实例且范围最小 | 短期,仅数分钟 | 较高,需客户端密钥管理与证明生成 |
| 短期 JWT+DPoP+ 平台完整性信号 | 最高,增加设备风险感知 | 短期,动态评估风险 | 高,需要设备证明验证和授权决策引擎 |
受众与范围声明:限定 AI API 操作边界
aud 应指向实际接收令牌的 AI API。资源服务器解析 JWT 后先确认自身位于受众列表,再检查 scope;即使令牌来自同一授权服务器,受众不匹配也应拒绝。这样能避免一个服务的令牌被直接拿到同一授权域的其他资源服务器使用。
scope 声明以空格分隔的字符串形式描述允许的操作。AI API 的 scope 应细分为模型推理、特定功能、配额水平等维度。例如仅授予 inference:gpt4.read 却不授予 training 或 admin 权限。授权服务器签发令牌时,必须基于用户权限与客户端请求的范围执行交集操作,绝不允许客户端单方面提升 scope。如果客户端请求 scope=inference:read training:write 而用户只有 inference:read 权限,授权服务器必须裁剪最终的 scope,杜绝权限膨胀,确保最小权限原则落地。
scope 的粒度取决于业务对象和操作类型。拆得过细会增加签发规则与客户端换取令牌的次数,拆得过粗又会放大单个令牌的权限。实践中可先按模型与操作划分,例如 infer、batch_infer 和 quota:read,再根据审计结果决定是否细化到具体端点。
在实际部署中,scope 的校验逻辑必须位于资源服务器端,而不能信任客户端传来的任何范围声明。攻击者可能尝试修改本地令牌副本中的 scope 字段,若服务端未重新校验签名和声明内容,就会导致权限绕过。因此,服务端必须使用授权服务器的公钥重新验证 JWT 签名,并解析出原始的 scope 列表进行比对。任何对 scope 的修改都会导致签名验证失败,从而被拦截。这一机制依赖于非对称加密算法的安全性,确保了声明的完整性。
| scope 值 | 允许的操作 | 风险等级 | 适用场景 |
|---|---|---|---|
| inference:read | 仅调用指定模型的推理接口 | 低 | 只读推理应用 |
| inference:read embedding:read | 同时允许推理和向量化 | 中 | 检索增强生成客户端 |
| training:write | 创建或微调模型训练任务 | 高 | 内部管理工具 |
| admin:config | 修改模型路由、配额等配置 | 极高 | 需严格授权的运维操作 |
过期时间:短寿命与刷新策略的平衡
exp 声明决定令牌的有效截止时间。短令牌可将泄露窗口压缩到分钟级,但若每个请求都需要重新获取令牌,授权服务器压力将急剧增大,同时引入额外的网络往返延迟,影响移动端响应体验。设计时必须在安全窗口与服务负载之间找到平衡,工程上倾向于将生命周期设置为数分钟,使得令牌即使被截获,其滥用窗口也远短于攻击者准备和扩散攻击所需的时间。频繁刷新的服务影响需由部署方自行评估,没有统一的标准数值。
资源服务器每次验证 exp,并只为基础设施时钟偏差保留有界容差。容差值由授权服务与资源服务器统一配置,不能由客户端提交,也不能为了减少刷新请求而跳过过期检查。监控中分别记录正常过期和时钟偏差拒绝,便于发现服务器时钟问题。
原生应用可使用授权码加 PKCE 获取访问令牌。若业务确实需要刷新令牌,授权服务器可采用轮换并检测旧令牌重复使用,同时设置绝对有效期和会话撤销入口。轮换策略属于服务端设计,不能仅凭客户端删除旧值就宣称防止了盗用。
在极端网络环境下,短有效期令牌可能导致用户操作中断。例如用户在弱网环境下发起请求,令牌在传输过程中过期,导致服务端返回 401 错误。此时客户端应具备自动重试机制,在捕获到过期错误后静默刷新令牌并重新发起请求。这一过程对用户应是透明的,不应弹出登录框或打断当前操作流程。然而,如果连续多次刷新失败,则可能意味着设备环境异常或账户被封禁,此时应终止会话并引导用户重新认证,以防止潜在的暴力破解或重放攻击。
| 有效期 | 泄露窗口 | 授权服务器压力 | 用户体验 |
|---|---|---|---|
| 小于 1 分钟 | 极窄 | 过高,可能熔断 | 频繁刷新,延迟增加 |
| 3~5 分钟 | 较短 | 可接受,需缓存 | 偶尔自动刷新,无明显感 |
| 10~15 分钟 | 适中 | 较低 | 请求内无明显刷新停顿 |
| 大于 30 分钟 | 过宽 | 低 | 流畅但风险剧增 |
持有人绑定:DPoP 降低重放攻击
即使令牌短期有效,攻击者仍可能在有效期内截获一次合法请求并尝试在另一上下文中重放。DPoP 机制通过将 access token 绑定到客户端持有的非对称密钥,要求每个请求都附带一个由该私钥签署的 DPoP 证明。资源服务器验证证明中的 jti 唯一性、htm 方法、htu 目标 URL 等字段,并对比证明内包含的 access token 哈希与当前请求的令牌,确保请求只能由持有对应私钥的客户端发起,没有对应私钥的攻击者无法生成有效证明,请求会被拒绝。
实施时,移动端首先生成密钥对,随后在向授权服务器请求令牌时提供公钥,授权服务器将所签发令牌的 cnf 确认声明与该公钥关联。后续每个 API 请求都必须生成新的 DPoP 证明,证明中必须包含目标令牌的 ath 声明。服务端验证时先确认证明签名有效,再计算当前访问令牌的哈希,与 ath 比对,如果哈希不匹配,即使令牌有效也拒绝请求。这一步将令牌从无记名凭证转变为必须与特定密钥绑定的凭证,大幅提升盗用难度,增加了攻击者的成本。
DPoP 显著减少了令牌重放威胁,但不能证明设备可信或用户真实意图。如果攻击者已完全控制持有密钥的移动设备本身,仍可在设备上生成有效证明,冒充合法用户请求。因此服务端最终授权不能仅依赖 DPoP,还必须结合平台完整性信号、用户认证上下文和业务行为异常检测。单独依靠 DPoP 而不实施短有效期或设备风险评估,会在设备被物理接管时留下授权缺口,无法防御内部威胁或高级持续性威胁。
DPoP 证明的生成必须在客户端安全环境中进行,避免私钥泄露。在 iOS 上应利用 Secure Enclave,在 Android 上应利用 TEE 支持的 KeyStore。私钥永远不应以明文形式出现在应用内存或磁盘中。每次生成证明时,应用调用系统提供的签名接口,传入待签数据,由硬件安全模块完成签名操作。这种设计确保了即使应用进程被调试或内存被转储,攻击者也无法提取私钥,从而保证了 DPoP 绑定的有效性,这是构建可信执行环境的关键一环。
| 步骤 | 检查内容 | 失败时的处理 | 依据 |
|---|---|---|---|
| 解析 DPoP 证明 | JWT 格式是否正确,alg 为 ES256 等 | 400 Bad Request | RFC 9449 |
| 验证签名 | 使用从 cnf 获取的公钥 | 401 Unauthorized | RFC 9449 |
| 检查绑定 | 证明中 ath 与 access token 哈希匹配 | 401 令牌绑定不匹配 | RFC 9449 |
| 校验时效 | iat、exp 在容许窗口内 | 401 证明过期或时钟偏移过大 | RFC 9449 |
移动端 DPoP 密钥的安全生成与存储
DPoP 机制要求客户端生成一对非对称密钥,并用私钥签署每次请求的证明。移动端必须确保该密钥对的私钥永远不离开硬件安全边界。在 iOS 平台上,应使用 Secure Enclave 生成基于 secp256r1 的椭圆曲线密钥对,并将私钥设置为不可提取;Secure Enclave 是与主处理器隔离的协处理器,即使内核被攻破也无法导出私钥。在 Android 平台上,应利用 AndroidKeyStore 系统服务,在硬件支持的密钥库中生成 EC 密钥对,并指定密钥的有效用途为签名,同时要求用户认证或设备解锁时才可访问。不论平台,开发者绝不能通过 KeyChain 或 KeyStore 导出私钥字节,也不能将其暂存于应用沙箱目录下,否则 DPoP 的持有人绑定意义将被完全瓦解。
生成 DPoP 证明时,应用可调用 iOS SecKeyCreateSignature 或 Android Signature,让不可导出的私钥完成签名。是否要求生物识别应按具体操作风险决定;后台推理若每次弹出认证会破坏可用性。较高风险的管理操作可采用用户确认,而普通推理请求可依赖设备密钥、短期令牌和服务端限额。
设备环境变化可以作为重新评估密钥绑定的信号。服务端可根据风险等级缩短令牌有效期、要求重新认证或撤销旧 cnf 公钥;是否重新生成密钥取决于平台能力与用户恢复流程。这样做提高的是异常状态下的控制可靠性,不代表平台信号能够证明设备绝对安全。
密钥的轮换策略也是安全管理的重要环节。长期不变的密钥增加了被破解的风险,尤其是在量子计算发展的背景下。虽然目前的椭圆曲线算法尚属安全,但定期轮换密钥是好习惯。服务端可以设定策略,强制客户端每隔一定时间或在检测到风险信号时重新注册公钥。这一过程应自动化完成,无需用户干预。客户端在检测到公钥失效后,应自动生成新密钥对并向授权服务器发起绑定请求,获取新的访问令牌。这种动态更新机制确保了即使旧密钥泄露,其有效期也被限制在轮换周期内。
- 生成密钥对时确保私钥不可导出,iOS 使用 SecureEnclave,Android 使用 AndroidKeyStore 且设置 setUserAuthenticationRequired 为 true
- 不在代码、日志或持久化存储中记录私钥明文或可导出格式
- 为签名操作绑定生物识别,避免无用户交互下签发 DPoP 证明
- 监听平台完整性信号,并在检测到环境降级时触发密钥废止与重新绑定流程
平台完整性信号:风险信号而非绝对信任
Apple App Attest 和 Google Play Integrity 可提供设备环境完整性断言。App Attest 要求在服务端验证证明并跟踪认证计数器,以此确认当前 app 实例未经篡改且未运行在越狱环境中。验证时服务端生成一次性 challenge,客户端返回断言对象,服务端调用 Apple 验证服务验签并检查 certificate 链,确保断言来自同一个设备实例。这种验证机制能够有效识别常见的越狱、动态调试和模块注入攻击,为服务端提供了重要的设备状态参考信息。
Play Integrity 标准请求允许传入 requestHash,将完整性响应与经过序列化规范的业务请求绑定。服务端需在收到响应后再计算一次请求的哈希,与返回的哈希比对,避免响应被重放到其他操作。该绑定可防止攻击者截获一次合法的完整性判断结果并重复使用。同时,非标准 API 返回结果不应被服务端采信,必须通过官方验证链路。整个过程结合一次性 nonce 或 requestHash,才能形成抗重放的设备环境验证,确保每次请求的设备状态都是实时且真实的。
这些完整性信号仅代表某一时刻的风险评估,并非二进制可信判定。设备可能被临时攻击工具绕过检测,或操作系统版本本身存在零日漏洞,而平台验证服务也未识别。因此这些信号只能作为加权的风险特征,需与令牌校验、DPoP 结果一并作为授权判断的输入,不应单独作为放行准则。如果仅凭完整性信号放行,攻击者可通过一次性绕过工具获取合法令牌后立即在干净环境中使用,跳过后续完整性检查,导致防御体系失效。
服务端可按完整性信号和业务风险采取不同动作:高风险请求拒绝或升级认证,中等风险限制敏感操作,低风险仍按令牌与 DPoP 规则校验。阈值要通过误拒率和事件记录持续调整,避免把平台信号当成唯一授权条件。
| 信号来源 | 可检测的风险 | 无法检测的风险 | 服务端处理建议 |
|---|---|---|---|
| App Attest | 越狱、动态调试、模块注入 | 内核漏洞、短时绕过 | 验证断言并绑定请求,结合令牌和用户行为 |
| Play Integrity | 设备完整性、应用未修改 | root 但隐藏痕迹、虚拟环境 | 验证 requestHash 绑定,非标准 API 返回结果不采信 |
| 联合使用两家 | 覆盖双平台主流攻击面 | 平台特定高级攻击 | 按平台分别验证,并交叉参考历史信号 |
| 无完整性信号 | 无 | 依赖令牌和 DPoP | 适当降低信任等级或要求额外认证 |
服务端最终授权:多因子校验流程
资源服务器收到移动端发起的 AI API 请求后,启动一个有序的校验流水线。第一步解析 JWT,检查其 alg 头、kid 等元数据,确保使用预期算法且签名来自已知签发者。如果 alg 为 none 或使用了弱算法,必须立即拒绝,防止算法降级攻击。第二步核验 iss、aud、exp 和 scope 等声明,只要任一声明不符合策略则直接返回 401 或 403,不允许降级处理。特别是 scope,必须确认令牌允许的操作完全覆盖当前请求的 API 操作,否则不能放行,确保权限控制的严密性。
若有 DPoP 绑定,服务端需以访问令牌中的 cnf 信息为基础,验证 DPoP 证明的完整性和加密绑定关系。验证步骤包括:提取 cnf 中的 jwk 公钥,验证 DPoP 证明签名;检查证明内的 htm 是否为请求方法,htu 是否匹配当前请求 URL;计算当前 access token 的哈希并与证明中的 ath 比对。任何一步失败都直接导致 401,不可因为某一项通过而忽略其他失败条件。这一步确保当前请求确实由持有对应私钥的客户端发出,不是简单的令牌重放,增强了请求的来源可信度。
第三步由服务端验证平台完整性断言,不采信客户端自行解释的结果。第四步综合令牌 scope、DPoP 证明和设备信号,输出允许、拒绝或升级认证。每个失败分支都要有明确策略与日志;哪些信号可以降级处理,需由业务风险规则定义。
授权日志可记录 jti、设备判定、请求时间、模型操作和最终动作,不保存完整令牌。RFC 9700 提供 OAuth 部署的通用安全原则,但不替 AI 业务定义权限。短时间内大量 DPoP 校验失败时,应上报异常并按来源、用户与会话维度限速,再由调查结果决定是否撤销令牌。
| 步骤 | 校验对象 | 依赖 | 失败退出码 |
|---|---|---|---|
| 解析 JWT | alg, kid, typ | 授权服务器公钥或 JWKS | 401 令牌格式错误 |
| 验证声明 | iss, aud, exp, scope | 服务端策略配置 | 401/403 声明不符 |
| 验证 DPoP | DPoP 证明的签名与绑定 | cnf 公钥、当前访问令牌 | 401 绑定无效或重放 |
| 验证平台信号 | App Attest/Play Integrity | 平台验证服务 | 403 设备风险信号高且策略需拒绝 |
- 确保授权服务器签发时已将 cnf 声明写入 JWT,且与客户端 DPoP 密钥匹配
- 定期轮换资源服务器与授权服务器之间的签名密钥
- 记录每次令牌校验的 jti,实现非重复使用检查
- 平台完整性验证需要防御重放,使用 challenge 或 requestHash
import sys
import json
import os
import base64
import time
def decode_payload(jwt_str):
parts = jwt_str.strip().split('.')
if len(parts) != 3:
raise ValueError('invalid JWT format')
payload_b64 = parts[1]
rem = len(payload_b64) % 4
if rem:
payload_b64 += '=' * (4 - rem)
return json.loads(base64.urlsafe_b64decode(payload_b64).decode('utf-8'))
def check_claims(payload):
if 'exp' not in payload:
sys.exit(2)
if payload['exp'] < time.time():
sys.exit(3)
expected_aud = os.environ.get('EXPECTED_AUD')
if expected_aud and payload.get('aud') != expected_aud:
sys.exit(4)
required_scope = os.environ.get('REQUIRED_SCOPE')
if required_scope:
scopes = payload.get('scope', '').split()
if not set(required_scope.split()).issubset(scopes):
sys.exit(5)
if __name__ == '__main__':
if len(sys.argv) != 2:
print('Usage: validate_jwt_claims.py <jwt>', file=sys.stderr)
sys.exit(1)
token = sys.argv[1]
try:
payload = decode_payload(token)
check_claims(payload)
print('claims valid')
except Exception as e:
print(f'Error: {e}', file=sys.stderr)
sys.exit(1)
设计权衡与移动端落地要点
短期范围令牌方案虽然提升了安全性,但也引入了客户端复杂性。移动端需要实现 DPoP 密钥对的安全生成和存储,在 iOS 中利用 Secure Enclave,在 Android 中使用 TEE 提供的 KeyStore,避免将私钥暴露在应用沙箱外。同时客户端必须正确实现 DPoP 证明的生成,包括构建 JWT header、payload 并签名,处理 nonce、htm 和 htu 等字段,任何实现偏差都有可能导致服务端拒绝合法请求或接受伪造证明。因此建议直接使用经过审计的 OAuth 库,而不是从零实现协议细节,以减少人为错误。
令牌生命周期的设计会直接影响用户体验。若过期太短且网络条件差,请求可能因令牌恰好在发送前过期而失败。此时客户端应在后台自动重试并静默刷新令牌,服务端应支持轻量级令牌刷新端点,且刷新响应中附带绑定到同一设备的新令牌与轮换刷新凭证。同时,客户端在收到 401 响应时,必须区分是令牌过期、scope 不足、还是 DPoP 绑定失败,从而采取不同的恢复策略,避免因误判导致无限刷新或用户被踢出,保持业务流程的连贯性。
服务端的监控也需相应调整,令牌的错误日志往往暴露整体攻击态势。例如短时间内大量过期令牌重放或 DPoP 校验失败,可能表明有攻击者在重放窗口内尝试批量请求。平台完整性信号若持续下降也应触发告警,并自动提升对应设备的认证要求。整体方案必须伴随可观测性体系建设,将令牌签发、刷新、校验以及完整性评估各个节点的指标拉取到监控平台,设置合理的阈值和告警规则,以便运维人员及时发现并响应潜在的安全威胁。
在项目实施过程中,团队需充分评估现有基础设施的支撑能力。引入 DPoP 和平台完整性验证可能需要升级授权服务器和资源服务器的软件版本,甚至改造现有的 API 网关。此外,移动端的改造涉及原生代码开发,测试工作量较大,需覆盖各种异常场景,如网络中断、设备重启、系统升级等。建议在灰度发布阶段密切监控各项指标,收集用户反馈,逐步扩大适用范围,确保新方案在提升安全性的同时,不会对业务稳定性造成负面影响。
事实依据与适用边界
以下内容区分官方事实、本文工程判断和不能外推的范围,避免把设计建议写成未经验证的产品结论。
| 本文判断 | 事实或工程依据 | 适用限制 |
|---|---|---|
| JWT 访问令牌可携带 issuer、audience、expiry、scope 与 client 标识供资源服务器进行结构化校验。 | RFC 9068 JWT access token profile | JWT 格式本身不保证令牌足够短命,也不保证签发策略正确。 |
| JWT 中的 exp 声明用于表示令牌的过期时间,资源服务器需强制校验。 | RFC 9068 JWT access token profile | RFC 9068 未规定过期时长的具体数值,也未处理时钟偏移容限的实施细节。 |
| DPoP 可将 access token 绑定到客户端持有的非对称密钥,并要求每个请求附上 DPoP 证明以降低令牌重放风险。 | RFC 9449 OAuth DPoP | DPoP 机制无法证明设备自身可信,也不能替代短有效期和服务端授权决策。 |
| DPoP 绑定要求客户端生成密钥对并证明所有权,服务器将令牌与公钥关联,后续请求必须提供由对应私钥生成的证明。 | RFC 9449 OAuth DPoP | 若攻击者完全控制客户端环境,DPoP 仍然可以被伪造,因此不能单独作为安全基石。 |
| OAuth 安全部署须限制重定向、防止令牌重放、避免授权码注入与不安全 grant 类型。 | RFC 9700 OAuth Security BCP | 该 BCP 不决定具体 AI 服务的商业权限模型,也不规定令牌范围或过期时长。 |
| 原生 App 属于公共客户端,不应使用客户端秘密,必须借助外部用户代理和 PKCE 达成安全授权。 | RFC 8252 OAuth 2.0 for Native Apps | RFC 8252 不定义业务 API 的最终 scope 和授权时长,也不涉及设备完整性信号。 |
| Apple App Attest 需要在服务端完成证明验证,并将断言绑定到特定请求,客户端的自我宣称不可采信。 | Apple App Attest server validation | App Attest 证明是一种风险信号,不能作为设备绝对可信或用户已授权的结论。 |
| Play Integrity 标准请求可通过 requestHash 把完整性响应与稳定序列化后的业务请求绑定,服务端重算哈希进行核对。 | Play Integrity standard requests | 完整性信号不是绝对可信根,最终允许或拒绝仍须由服务端结合业务上下文和令牌校验结果共同决定。 |
工程常见问题
为什么移动端不能直接使用长期有效的 API 密钥调用 AI 接口?
移动应用属于公共客户端,无法安全保存密钥。任意一次反编译或中间人攻击都可能泄露长期密钥,导致 AI 资源被无限制滥用,成本和安全后果严重。短期范围令牌可将暴露窗口压缩至分钟级,且 scope 限制使泄露影响可控。
DPoP 能否完全防止令牌重放?
DPoP 通过绑定密钥显著减少重放,但无法防御持有密钥的客户端自身被攻破的情况。仍需配合短有效期和服务端多因子授权,例如加入设备完整性信号,才能形成纵深防护。
服务端验证 JWT 声明是否可以跳过签名?
不可以。生产环境中必须先验证 JWT 签名,确保令牌由授权服务器签发且未被篡改。任何跳过签名验证的行为都将导致严重的安全漏洞,使攻击者能够伪造任意声明。
平台完整性信号能否作为唯一的放行依据?
不能。平台证明只是一种动态风险信号,不能排除设备被高级攻击手段临时绕过检测。服务端必须综合令牌、DPoP、用户行为和业务上下文做出最终授权,不可单独依赖完整性判定。
过期时间设置多短才足够?
具体时长取决于业务风险承受能力和 API 调用频次。工程上倾向于设置在几分钟量级,这样即便令牌泄露,攻击者也只是在极短窗口内滥用。过短的令牌会导致频繁刷新,影响体验和服务器负载。
刷新令牌是否可以保存在移动端?
可以,但必须采用可轮换的刷新令牌机制,即将刷新令牌也绑定到设备环境,每次使用后签发新的刷新令牌并废弃旧令牌。不建议无轮换的长期刷新令牌暴露于移动端。