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

通过Cloud CDN访问GCP存储桶时遇`signed_request_invalid_format`错误

排查Cloud CDN签名Cookie引发的403错误(signed_request_invalid_format)

问题背景

使用签名Cookie通过Cloud CDN访问GCP存储桶中的受限文件,已通过自定义函数生成Cookie并发送至CDN,但访问返回403禁止错误,负载均衡日志显示状态详情为signed_request_invalid_format。

签名Cookie生成代码

signCookie(urlPrefix: string, keyName: string, key: string, expires: number) {
    // Base64url encode the url prefix
    const urlPrefixEncoded = Buffer.from(urlPrefix).toString('base64url');

    // Input to be signed
    const input = `URLPrefix=${urlPrefixEncoded}:Expires=${expires}:KeyName=${keyName}`;

    // Create bytes from given key string.
    const keyBytes = Buffer.from(key, 'base64');

    // Use key bytes and crypto.createHmac to produce a base64 encoded signature which is then escaped to be base64url encoded.
    const signature = createHmac('sha1', keyBytes).update(input).digest('base64url');

    // Adding the signature on the end if the cookie value
    const signedValue = `${input}:Signature=${signature}`;

    return signedValue;
}

错误信息

Error: Forbidden
Your client does not have permission to get URL ********/sample.pdf from this server.

负载均衡日志详情:statusDetails: "signed_request_invalid_format"

排查与修复建议

  • 检查URL前缀的Base64url编码:GCP要求编码后必须移除所有填充字符=,虽然Node.js的toString('base64url')默认会处理,但需确认实际生成的urlPrefixEncoded无多余=,必要时手动去除:
    const urlPrefixEncoded = Buffer.from(urlPrefix).toString('base64url').replace(/=/g, '');
    
  • 验证签名输入的字段顺序与拼写:GCP严格要求字段顺序为URLPrefix→Expires→KeyName,且字段名必须完全匹配(注意大写),不能出现拼写错误。
  • 确认签名的Base64url编码合规:部分Node.js版本的base64url编码可能存在差异,可手动实现确保符合GCP标准:
    const signature = createHmac('sha1', keyBytes)
      .update(input)
      .digest('base64')
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=/g, '');
    
  • 检查Cookie名称:Cloud CDN要求签名Cookie的名称必须是Cloud-CDN-Cookie,名称错误会直接导致格式无效。
  • 验证Expires时间戳:expires必须是秒级Unix时间戳,如果传入的是毫秒级时间戳,需除以1000取整:
    const expires = Math.floor(Date.now() / 1000) + 3600; // 示例:1小时后过期
    
  • 确认密钥正确性:确保key参数是从GCP控制台获取的签名密钥私有密钥(Base64格式),而非公钥或其他格式密钥。

验证步骤

  1. 打印生成的signedValue,检查格式是否严格符合URLPrefix=xxx:Expires=xxx:KeyName=xxx:Signature=xxx,无多余空格或特殊字符。
  2. 使用GCP官方签名工具重新生成签名Cookie,对比自定义函数的生成结果是否一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:02:39