想使用NODEJS为IBM CLOUD OBJECT STORAGE生成一个预签名的url,这样最终用户只需单击url就可以下载对象,而我不必向所有用户提供COS访问权限。
我创建了一个存储桶,并使用{“ HMAC”:true}创建了服务凭证,因此生成了HMAC访问ID和秘密密钥。我使用了此处提供的代码(https://console.bluemix.net/docs/services/cloud-object-storage/hmac/presigned-urls.html#create-a-presigned-url);网址已生成,但尝试访问该网址时,出现错误404,无法获取/ v2 / endpoints / bucket_name / file_name, 该文件已经存在于相应的存储桶中。
这是使用的代码
const crypto = require('crypto');
const moment = require('moment');
const httpMethod = 'GET';
const host = 'control.cloud-object-storage.cloud.ibm.com/v2/endpoints';
const signature_endpoint = 'https://' + host
const expiration = 86400 // time in seconds
const signature_access_key = '**********************'; // cos_hmac_keys.access_key_id
const signature_secret_key = '************************'; //cos_hmac_keys..secret_access_key
function hashHex(msg) {
var hash = crypto.createHash('sha256');
hash.update(msg);
return hash.digest('hex');
}
function hash(key, msg) {
var hmac = crypto.createHmac('sha256', key);
hmac.update(msg, 'utf8');
return hmac.digest();
}
function createSignatureKey(key, datestamp, region, service) {
keyDate = hash(('AWS4' + key), datestamp);
keyString = hash(keyDate, region);
keyService = hash(keyString, service);
keySigning = hash(keyService, 'aws4_request');
return keySigning;
}
function hmacHex(key, msg) {
var hmac = crypto.createHmac('sha256', key);
hmac.update(msg, 'utf8');
return hmac.digest('hex');
}
function return_signature(filename) {
var time = moment().utc();
var timestamp = time.format('YYYYMMDDTHHmmss') + 'Z';
var datestamp = time.format('YYYYMMDD');
var standardizedQuerystring = 'X-Amz-Algorithm=AWS4-HMAC-SHA256' +
'&X-Amz-Credential=' + encodeURIComponent(signature_access_key +
'/' + datestamp + '/' + region + '/s3/aws4_request') +
'&X-Amz-Date=' + timestamp +
&X-Amz-Expires=' + expiration.toString() +
'&X-Amz-SignedHeaders=host';
var standardizedResource = '/' + bucketName + '/' + filename;
var payloadHash = 'UNSIGNED-PAYLOAD';
var standardizedHeaders = 'host:' + host;
var signedHeaders = 'host';
var standardizedRequest = httpMethod + '\n' +
standardizedResource + '\n' +
standardizedQuerystring + '\n' +
standardizedHeaders + '\n' +
'\n' +
signedHeaders + '\n' +
payloadHash;
// assemble string-to-sign
var hashingAlgorithm = 'AWS4-HMAC-SHA256';
var credentialScope = datestamp + '/' + region + '/' + 's3' + '/' +
'aws4_request';
var sts = hashingAlgorithm + '\n' +
timestamp + '\n' +
credentialScope + '\n' +
hashHex(standardizedRequest);
signatureKey = createSignatureKey(signature_secret_key, datestamp,
region, 's3');
signature = hmacHex(signatureKey, sts);
var requestUrl = signature_endpoint + '/' +
bucketName + '/' +
filename + '?' +
standardizedQuerystring +
'&X-Amz-Signature=' +
signature;
console.log(`requestUrl: ${requestUrl}`);
console.log(`\nSending ${httpMethod} request to IBM COS - ---------
-------------`);
console.log('Request URL = ' + requestUrl);
// create and send the request
console.log(`\nSending ${httpMethod} request to IBM COS -----------
------------`);
console.log('Request URL = ' + requestUrl);
var request = https.get(requestUrl, function (response) {
console.log('\nResponse from IBM COS ------------------------------
----');
console.log(`Response code: ${response.statusCode}\n`);
response.on('data', function (chunk) {
console.log("response from request URL-------------------")
console.log('Response: ' + chunk);
});
});
request.end();
return requestUrl;
}