Skip to content

Commit

Permalink
Host 参与签名计算
Browse files Browse the repository at this point in the history
  • Loading branch information
carsonxu committed Aug 6, 2021
1 parent 1eb19cc commit 32c5c08
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 4 deletions.
8 changes: 8 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ declare namespace COS {
SecretId: string,
/** 计算签名用的密钥 SecretKey,必选 */
SecretKey: string,
/** 请求的存储桶,如果传入了 Bucket、Region,签名会默认加上 Host 字段,可选 */
Bucket?: Bucket,
/** 请求的地域,如果传入了 Bucket、Region,签名会默认加上 Host 字段,可选 */
Region?: Region,
/** 请求方法,可选 */
Method?: Method,
/** 请求路径,最前面带 /,例如 /images/1.jpg,可选 */
Expand Down Expand Up @@ -1877,6 +1881,10 @@ Bulk:批量模式,恢复时间为24 - 48小时。 */
SecretId?: string,
/** 计算签名用的密钥 SecretKey,如果不传会用实例本身的凭证,可选 */
SecretKey?: string,
/** 请求的存储桶,如果传入了 Bucket、Region,签名会默认加上 Host 字段,可选 */
Bucket?: Bucket,
/** 请求的地域,如果传入了 Bucket、Region,签名会默认加上 Host 字段,可选 */
Region?: Region,
/** 请求方法 */
Method?: Method,
/** 请求的对象键,最前面不带 /,例如 images/1.jpg */
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cos-nodejs-sdk-v5",
"version": "2.9.21",
"version": "2.10.0",
"description": "cos nodejs sdk v5",
"main": "index.js",
"types": "index.d.ts",
Expand Down
47 changes: 44 additions & 3 deletions sdk/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,17 @@ function getService(params, callback) {
domain = protocol + '//service.cos.myqcloud.com';
}

var SignHost = '';
var standardHost = region ? 'cos.' + region + '.myqcloud.com' : 'service.cos.myqcloud.com';
var urlHost = domain.replace(/^https?:\/\/([^/]+)(\/.*)?$/, '$1');
if (standardHost === urlHost) SignHost = standardHost;

submitRequest.call(this, {
Action: 'name/cos:GetService',
url: domain,
method: 'GET',
headers: params.Headers,
SignHost: SignHost,
}, function (err, data) {
if (err) return callback(err);
var buckets = (data && data.ListAllMyBucketsResult && data.ListAllMyBucketsResult.Buckets
Expand Down Expand Up @@ -3022,6 +3028,8 @@ function getAuth(params) {
return util.getAuth({
SecretId: params.SecretId || this.options.SecretId || '',
SecretKey: params.SecretKey || this.options.SecretKey || '',
Bucket: params.Bucket,
Region: params.Region,
Method: params.Method,
Key: params.Key,
Query: params.Query,
Expand Down Expand Up @@ -3067,19 +3075,27 @@ function getObjectUrl(params, callback) {

var queryParamsStr = '';
if(params.Query){
queryParamsStr += util.obj2str(params.Query);
queryParamsStr += util.obj2str(params.Query);
}
if(params.QueryString){
queryParamsStr += (queryParamsStr ? '&' : '') + params.QueryString;
queryParamsStr += (queryParamsStr ? '&' : '') + params.QueryString;
}

// 签名加上 Host,避免跨桶访问
var SignHost = '';
var standardHost = 'cos.' + params.Region + '.myqcloud.com';
if (!self.options.ForcePathStyle) standardHost = params.Bucket + '.' + standardHost;
var urlHost = url.replace(/^https?:\/\/([^/]+)(\/.*)?$/, '$1');
if (standardHost === urlHost) SignHost = standardHost;

var syncUrl = url;
if (params.Sign !== undefined && !params.Sign) {
queryParamsStr && (syncUrl += '?' + queryParamsStr);
callback(null, {Url: syncUrl});
return syncUrl;
}

var SignHost = getSignHost.call(this, {Bucket: params.Bucket, Region: params.Region, Url: url});
var AuthData = getAuthorizationAsync.call(this, {
Action: ((params.Method || '').toUpperCase() === 'PUT' ? 'name/cos:PutObject' : 'name/cos:GetObject'),
Bucket: params.Bucket || '',
Expand All @@ -3088,7 +3104,8 @@ function getObjectUrl(params, callback) {
Key: params.Key,
Expires: params.Expires,
Headers: params.Headers,
Query: params.Query
Query: params.Query,
SignHost: SignHost,
}, function (err, AuthData) {
if (!callback) return;
if (err) {
Expand Down Expand Up @@ -3234,14 +3251,36 @@ function getUrl(params) {
return url;
}

var getSignHost = function (opt) {
if (!opt.Bucket || !opt.Bucket) return '';
var ps = this.options.ForcePathStyle;
var url = opt.Url || getUrl({
ForcePathStyle: ps,
protocol: this.options.Protocol,
domain: this.options.Domain,
bucket: opt.Bucket,
region: opt.Region,
});
var standardHost = (ps ? '' : opt.Bucket + '.') + 'cos.' + opt.Region + '.myqcloud.com';
var urlHost = url.replace(/^https?:\/\/([^/]+)(\/.*)?$/, '$1');
if (standardHost === urlHost) return standardHost;
return '';
}

// 异步获取签名
function getAuthorizationAsync(params, callback) {

var headers = util.clone(params.Headers);
var headerHost = '';
util.each(headers, function (v, k) {
(v === '' || ['content-type', 'cache-control', 'expires'].indexOf(k.toLowerCase()) > -1) && delete headers[k];
if (k.toLowerCase() === 'host') headerHost = v;
});

// Host 加入签名计算
if (!headerHost && params.SignHost) headers.Host = params.SignHost;


// 获取凭证的回调,避免用户 callback 多次
var cbDone = false;
var cb = function (err, AuthData) {
Expand Down Expand Up @@ -3479,6 +3518,7 @@ function submitRequest(params, callback) {
var Query = util.clone(params.qs);
params.action && (Query[params.action] = '');

var SignHost = params.SignHost || getSignHost.call(this, {Bucket: params.Bucket, Region: params.Region});
var next = function (tryTimes) {
var oldClockOffset = self.options.SystemClockOffset;
getAuthorizationAsync.call(self, {
Expand All @@ -3488,6 +3528,7 @@ function submitRequest(params, callback) {
Key: params.Key,
Query: Query,
Headers: params.headers,
SignHost: SignHost,
Action: params.Action,
ResourceKey: params.ResourceKey,
Scope: params.Scope,
Expand Down
3 changes: 3 additions & 0 deletions sdk/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ var getAuth = function (opt) {
pathname.indexOf('/') !== 0 && (pathname = '/' + pathname);
}

// 如果有传入存储桶,那么签名默认加 Host 参与计算,避免跨桶访问
if (!headers.Host && !headers.host && opt.Bucket && opt.Region) headers.Host = opt.Bucket + '.cos.' + opt.Region + '.myqcloud.com';

if (!SecretId) throw new Error('missing param SecretId');
if (!SecretKey) throw new Error('missing param SecretKey');

Expand Down

0 comments on commit 32c5c08

Please sign in to comment.