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

Google Cloud CDN签名Cookie无效:Firebase生成后请求报403

问题:Google Cloud CDN签名Cookie返回403(signed_request_invalid_signature)

我正在使用Firebase Cloud Functions为Google Cloud CDN生成签名Cookie,生成函数如下:

function signCookie(
    urlPrefix,
    keyName,
    key,
    expirationTimeSec,
) {
    // URL-safe base64 encode the URL prefix
    const encodedUrlPrefix = Buffer.from(urlPrefix)
        .toString("base64")
        .replace(/\+/g, "-")
        .replace(/\//g, "_");

    // Construct the policy string
    const policy = `URLPrefix=${encodedUrlPrefix}:Expires=${expirationTimeSec}:KeyName=${keyName}`;

    // Decode the base64 key
    const keyBytes = Buffer.from(key, "base64");

    // Create an HMAC-SHA1 signature
    const signature = crypto
        .createHmac("sha1", keyBytes)
        .update(policy)
        .digest("base64")
        .replace(/\+/g, "-") // Make it URL-safe
        .replace(/\//g, "_");

    // Construct the full cookie value
    return {
        cookieValue: `${policy}:Signature=${signature}`,
        expires: new Date(expirationTimeSec * 1000).toUTCString()
    }
}

Cookie已正确下发,在Chrome开发者工具的Application标签中可见,且CDN媒体请求的请求头中已包含该Cookie,但请求仍返回403状态码,Google Cloud控制台日志显示statusDetails为signed_request_invalid_signature。请问这是否是Firebase Functions修改了Cookie导致的问题?或是跨域问题?我的客户端网站部署在subdomain.domain.com,CDN部署在cdn.domain.com。


排查与解决方案

1. 排除Firebase Functions修改Cookie的可能

  • 在函数中添加日志,输出生成的完整cookieValue,再和浏览器Application标签里的Cookie值对比。如果两者完全一致,说明Firebase Functions没有修改Cookie;如果不一致,检查函数返回后的响应头设置逻辑(是否存在额外的转义、截断操作)。

2. 核心排查:签名本身的问题(signed_request_invalid_signature的主要原因)

  • URLPrefix编码缺失处理:Google要求URLPrefix使用不带填充字符=的URL-safe base64编码。你的代码目前只替换了+和/,需要额外去掉末尾的=:
    const encodedUrlPrefix = Buffer.from(urlPrefix)
        .toString("base64")
        .replace(/\+/g, "-")
        .replace(/\//g, "_")
        .replace(/=+$/, ""); // 新增:移除末尾的填充=
    
  • 时间戳验证:确认expirationTimeSec是秒级Unix时间戳,且当前时间早于该时间戳(Cookie未过期)。如果误用毫秒级时间戳,会导致Expires值无效。
  • 密钥与密钥名匹配:确保函数中使用的key是GCP控制台生成签名密钥时的base64格式私钥,且keyName与控制台内的密钥名称完全一致(大小写敏感)。
  • Policy字符串格式:检查Policy字段间的分隔符是英文冒号:,无多余空格。例如URLPrefix=xxx:Expires=xxx:KeyName=xxx,字段间不能存在空格。
  • 签名算法匹配:GCP控制台的签名密钥算法需与代码一致。如果控制台用的是SHA256,需将代码中的createHmac("sha1", keyBytes)改为createHmac("sha256", keyBytes)。

3. 跨域相关排查(虽请求已带Cookie,但仍需确认)

  • Cookie的Domain设置:客户端部署在subdomain.domain.com,CDN在cdn.domain.com,需将Cookie的Domain设为.domain.com(开头的点不可省略),确保两个子域名都能携带该Cookie。
  • SameSite属性:若Cookie的SameSite设为Strict,跨域请求不会携带;需设为Lax或None(配合Secure属性)才能支持跨域携带。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:52:19