You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义认证令牌存储最佳实践及安全风险规避方案咨询

针对Widget令牌盗用风险的解决方案

1. 绑定请求上下文的令牌验证

  • 令牌嵌入请求来源特征:生成令牌时,把当前客户站点的域名、浏览器UA的哈希片段(比如取UA前50位+域名做SHA256哈希)作为加密参数和用户ID一起加密。后端验证时,先解密令牌,重新计算当前请求的来源特征哈希,和令牌内的比对,不一致直接拒绝。
    • PHP代码示例:
      // 生成令牌时的来源特征计算
      $sourceHash = hash('sha256', $_SERVER['HTTP_HOST'] . substr($_SERVER['HTTP_USER_AGENT'], 0, 50));
      // 将$sourceHash与用户ID一起加密生成令牌
      
  • 短令牌+刷新机制:拆分令牌为访问令牌(15-30分钟有效期,存在Widget内存中,页面刷新即失效)和刷新令牌(7天左右有效期,存在客户站点的HttpOnly、Secure、SameSite=Strict Cookie中)。每次接口请求用访问令牌,过期后通过Cookie自动携带的刷新令牌向后端换取新的访问令牌,同时更新刷新令牌。

2. 浏览器指纹辅助验证

  • 绑定稳定指纹:用户登录时,收集浏览器的稳定特征(屏幕分辨率、时区、语言列表、WebGL指纹哈希等),将指纹哈希和用户ID一同加密到令牌内。后续每次请求Widget接口时,前端重新计算当前浏览器的指纹哈希,传给后端和令牌内的哈希比对,匹配度低于阈值(比如90%)则触发二次验证(短信/邮箱验证码)。
    • JS代码示例(指纹计算):
      async function generateFingerprint() {
        const features = [
          navigator.userAgent,
          screen.width,
          screen.height,
          Intl.DateTimeFormat().resolvedOptions().timeZone,
          navigator.language
        ].join('|');
        const encoder = new TextEncoder();
        const hashBuffer = await crypto.subtle.digest('SHA-256', encoder.encode(features));
        // 转成十六进制字符串
        return Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('');
      }
      
  • 设置匹配阈值:允许指纹有小范围变化(比如用户调整窗口大小),通过计算特征相似度判断是否合法,而非要求完全一致。

3. 限制令牌使用范围

  • 绑定Widget实例:令牌内嵌入用户在该客户站点创建的Widget ID,后端验证时仅允许对应Widget的请求使用该令牌,避免令牌跨Widget盗用。
  • 单会话令牌机制:后端存储每个用户的有效令牌列表,每次令牌使用时检查是否为当前活跃会话的令牌。若检测到同一令牌在不同上下文(不同IP、不同指纹)被使用,立即失效该令牌并通知用户。

4. 强化存储安全

  • 优先使用HttpOnly Cookie:刷新令牌存在客户站点的Cookie中,标记HttpOnly(JS无法读取)、Secure(仅HTTPS传输)、SameSite=Strict(仅同站请求携带),从根源减少XSS盗用风险。
  • 前端二次加密:若必须用前端存储(如Cookie无法使用),用客户站点域名的哈希作为密钥,对令牌做AES加密后再存入localStorage。即使令牌被窃取,没有域名密钥也无法解密使用。

内容的提问来源于stack exchange,提问作者b4tch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 11:18:21