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

Google Cloud CDN URLPrefix签名URL生成失败求助

Troubleshooting Invalid URLPrefix Signed URLs for Google Cloud CDN

Let's break down the issues in your implementation and fix them step by step—since your single-file signed URLs work, we know the core setup (backend bucket, CDN config, keys) is valid, so the problem is in how you're generating the prefix-signed URLs.

Key Issues in Your Current Code

1. Using HTML-escaped & Instead of Raw & in Signature Payload

Google Cloud CDN expects the signature to be computed against a string with raw & separators between parameters, not HTML-escaped &. When you sign a string with &, the resulting signature won't match what the CDN calculates when it parses the actual URL parameters.

2. Incorrect Expires Timestamp Format

Your code uses new Date().getTime() + opts.expires which returns a millisecond timestamp, but Cloud CDN requires the Expires parameter to be a Unix timestamp in seconds. Using milliseconds will set an invalid expiration time (far in the future, which might be treated as invalid).

3. Potential URLPrefix Mismatch

Ensure the URLPrefix value exactly matches the prefix of the request URL (including protocol, domain, and path). For example, if you're requesting https://my-server/sample/360p/video.mp4, the URLPrefix should be https://my-server/sample/360p/ (or https://my-server/sample/360p—trailing slash is optional but must align with your request path).

Fixed Implementation

Here's the corrected signCdnUrl3 function addressing all the above issues:

import { createHmac } from 'crypto';
import Base64urlUtil from './Base64urlUtil'; // Adjust import path as needed

export interface SignedUrlOptions {
  baseUrl: string;
  keyName: string;
  keyBase64: string;
  expires: number; // Expiration time in milliseconds (e.g., 3600000 for 1 hour)
}

export function signCdnUrl3(fileName: string, opts: SignedUrlOptions, urlPrefix?: string) {
  // Calculate Unix timestamp in seconds (not milliseconds)
  const expireVal = Math.floor((Date.now() + opts.expires) / 1000).toString();
  
  let paramsToSign: string;
  if (urlPrefix) {
    const urlPrefixCombined = `${opts.baseUrl}${urlPrefix}`;
    const urlPrefixEncoded = Base64urlUtil.encode(urlPrefixCombined);
    // Use raw & separators, not &
    paramsToSign = `URLPrefix=${urlPrefixEncoded}&Expires=${expireVal}&KeyName=${opts.keyName}`;
  } else {
    // Fallback to single-file signing if no prefix is provided
    const urlToSign = `${opts.baseUrl}/${fileName}?Expires=${expireVal}&KeyName=${opts.keyName}`;
    paramsToSign = urlToSign.split('?')[1]!;
  }

  // Compute signature
  const keyBuffer = Buffer.from(opts.keyBase64, 'base64');
  let signature = createHmac('sha1', keyBuffer).update(paramsToSign).digest('base64');
  signature = Base64urlUtil.escape(signature);

  // Build the final URL with raw & separators
  const finalUrl = `${opts.baseUrl}/${fileName}?${paramsToSign}&Signature=${signature}`;
  return finalUrl;
}

Additional Troubleshooting Steps

  • Verify Signature Payload: To debug, log the paramsToSign string before signing it. Compare it against what Cloud CDN expects: it should be exactly URLPrefix=<base64url-encoded-prefix>&Expires=<unix-seconds>&KeyName=<your-key-name>.
  • Check Load Balancer Logs: Look for the specific error in the load balancer logs (under Cloud Logging > Cloud Load Balancing > HTTP(S) Load Balancers). Common errors include:
    • signature_invalid: The signature doesn't match the payload (most likely due to incorrect & usage or timestamp format).
    • signature_expired: The Expires timestamp is in the past (confirm your server's clock is synchronized).
  • Validate URLPrefix Encoding: Cross-check your encoded prefix with standard base64url rules—ensure there are no padding characters (=) in the final encoded string (your Base64urlUtil.escape method already handles this correctly).
  • Test with a Fixed Expiration: Hardcode a future Unix timestamp (e.g., 1735689600 for January 1, 2025) to rule out timestamp calculation issues.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 11:12:29