Google Cloud Storage 从 CDN npm 获取 signedUrl

Google Cloud Storage get signedUrl from CDN npm

我正在使用如下代码为我的内容创建签名 Url:

var storage = require('@google-cloud/storage')();
var myBucket = storage.bucket('my-bucket');
var file = myBucket.file('my-file');

//-
// Generate a URL that allows temporary access to download your file.
//-
var request = require('request');

var config = {
  action: 'read',
  expires: '03-17-2025'
};

file.getSignedUrl(config, function(err, url) {
  if (err) {
    console.error(err);
    return;
  }

  // The file is now available to read from the URL.

});

这将创建一个以 https://storage.googleapis.com/my-bucket/

开头的 Url

如果我将 URL 放在浏览器中,它是可读的。

但是,我猜 URL 是对存储桶文件的直接访问,而不是通过我配置的 CDN。

我在文档 (https://cloud.google.com/nodejs/docs/reference/storage/1.6.x/File#getSignedUrl) 中看到您可以传递一个 cname 选项,它将 url 转换为将 https://storage.googleapis.com/my-bucket/ 替换为我的存储桶 CDN。

然而,当我复制结果 URL 时,服务帐户或结果 url 似乎无法访问资源。

我已将 firebase 管理服务帐户添加到存储桶,但仍然无法访问。

此外,从文档来看,CDN 签名 url 似乎与通过 API 签名的有很大不同。是否可以从 api 创建一个 CDN 签名 url,或者我应该按照 https://cloud.google.com/cdn/docs/using-signed-urls?hl=en_US&_ga=2.131493069.-352689337.1519430995#configuring_google_cloud_storage_permissions 中的说明手动创建它?

任何对该签名的节点代码感兴趣的人:

    var url = 'URL of the endpoint served by Cloud CDN';
    var key_name = 'Name of the signing key added to the Google Cloud Storage bucket or service';
    var key = 'Signing key as urlsafe base64 encoded string';
    var expiration = Math.round(new Date().getTime()/1000) + 600; //ten minutes after, in seconds

    var crypto = require("crypto");
    var URLSafeBase64 = require('urlsafe-base64');

    // Decode the URL safe base64 encode key
    var decoded_key = URLSafeBase64.decode(key);

    // buILD URL
    var urlToSign = url 
            + (url.indexOf('?') > -1 ? "&" : "?")
            + "Expires=" + expiration
            + "&KeyName=" + key_name;

    //Sign the url using the key and url safe base64 encode the signature
    var hmac = crypto.createHmac('sha1', decoded_key); 
    var signature = hmac.update(urlToSign).digest();
    var encoded_signature = URLSafeBase64.encode(signature);

    //Concatenate the URL and encoded signature
    urlToSign += "&Signature=" + encoded_signature;

Cloud CDN 内容分发网络与 HTTP(S) 负载平衡配合使用,向您的用户分发内容。您是否使用 HTTPS 负载均衡器向您的用户传送内容? 您可以查看此附件文档[1],了解如何使用 Google Cloud CDN 和 HTTP(S) 负载平衡以及将内容插入缓存。

[1] https://cloud.google.com/cdn/docs/overview [2] https://cloud.google.com/cdn/docs/concepts

您收到什么错误代码?您能否使用 curl 命令并发送带有错误代码的输出以供进一步分析。

您能否确认您所做的配置是否满足可缓存性的要求,因为并非所有的 HTTP 响应都是可缓存的? Google云CDN只缓存满足特定条件[3]的响应,请确认。确认后,我会做进一步的调查,并相应地建议您。

[3] 可缓存性:https://cloud.google.com/cdn/docs/caching#cacheability

你能给我提供下面这两个命令的输出,这将帮助我验证这些对象是否存在权限问题?这些命令将转储对象上的所有当前权限设置。

gsutil acl 获取 gs://[full_path_to_file_to_be_cached] gsutil ls -L gs://[full_path_to_file_to_be_cached]

有关权限的更多详细信息,请参阅此 GCP 文档 [4]

[4] 设置存储桶权限:https://cloud.google.com/storage/docs/cloud-console#_bucketpermission

不,无法从 API 创建 CDN 签名 URL

来自 Google 文档 here。 @htafoya 提供的答案似乎是合法的。 但是,我花了几个小时来解决为什么已签名的 URL 无法作为 CDN 端点工作而抱怨访问被拒绝。最终我发现使用 crypto 模块的代码不会产生与 gcloud compute sign-url 计算的相同的 hmac-sha1 哈希值,我仍然不知道为什么。

同时,我看到this lib(jsSHA)很酷,它生成的HMAC-SHA1哈希值与gcloud完全一样,而且它有一个整洁的API, 所以我想我应该在这里发表评论,这样如果其他人有同样的斗争就会从中受益,这是我用来签署 gcloud cdn URL:

的最终代码
    import jsSHA from 'jssha';
    const url = `https://{domain}/{path}`;
    const expire = Math.round(new Date().getTime() / 1000) + daySeconds;
  const extendedUrl = `${url}${url.indexOf('?') > -1 ? "&" : "?"}Expires=${expire}&KeyName=${keyName}`;

  // use jssha
  const shaObj = new jsSHA("SHA-1", "TEXT", { hmacKey: { value: signKey, format: "B64" } });
  shaObj.update(extendedUrl);
  const signature = safeSign(shaObj.getHMAC('B64'));
  return `${extendedUrl}&Signature=${signature}`;

工作得很好!