我正在使用以下代码为我的内容创建一个签名的网址:
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是对存储桶文件的直接访问,并且没有通过我配置的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签名的URL似乎有很大不同。是否可以从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中的说明手动创建它?
答案 0 :(得分:0)
对于对该签名的节点代码感兴趣的任何人:
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;
答案 1 :(得分:0)
Cloud CDN内容交付网络可与HTTP(S)负载平衡配合使用,以将内容交付给您的用户。您是否正在使用HTTPS负载平衡器向用户交付内容? 您可以在使用Google Cloud CDN和HTTP(S)负载平衡以及将内容插入缓存中看到此附件文档[1]。
[1] https://cloud.google.com/cdn/docs/overview [2] https://cloud.google.com/cdn/docs/concepts
您得到什么错误代码?您可以使用curl命令并发送带有错误代码的输出以进行进一步分析吗?
由于不是所有HTTP响应都是可缓存的,您是否可以确认所做的配置符合可缓存性的要求? Google Cloud 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
答案 2 :(得分:0)
来自 Google 文档 here。 @htafoya 提供的答案似乎是合法的。
但是,我花了几个小时来思考为什么签名 URL 不起作用,因为 CDN 端点抱怨访问被拒绝。最终我发现使用 crypto
模块的代码不会产生与 gcloud compute sign-url
计算的相同的 hmac-sha1 哈希值,我仍然不知道为什么。
同时,我看到 this lib (jsSHA) 非常酷,它生成与 gcloud
完全相同的 HMAC-SHA1 哈希值,并且它有一个简洁的 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}`;
工作很棒!